ivan-hc / AM

AppImage package manager to install, update and manage ALL of them, system-wide or locally, thanks to its ever-growing AUR-inspired database listing 2500+ portable apps and programs for GNU/Linux. The first, real centralized repository to manage your AppImages with the ease of APT and the power of PacMan.
https://portable-linux-apps.github.io
GNU General Public License v3.0
509 stars 40 forks source link

Add support for AppBundle, FlatImage... and other formats! #1099

Open ivan-hc opened 1 week ago

ivan-hc commented 1 week ago

I'm the author of the AppBundle format and tooling, integration is fairly easy to do. You can use the following flags if you already handle integration for AppImages: --pbundle_link, this command is provided by the runtime and lets you run any command but from within the AppBundle. Its very powerful. Let's you do this, for example: --pbundle_link sh -c "cp \$SELF_TEMPDIR/.DirIcon ~/.local/share/icons/firefox.png" You also have the following commands: --pbundle_desktop | base64 -d --pbundle_pngIcon | base64 -d --pbundle_appstream | base64 -d --pbundle_list

You can check the exact build-date of an AppBundle via --pbundle_help.

I'm working on AppBundleHUB, which should provide metadata for the AppBundles it generates. If you've looked at any of the recipes, you'll realice they're mostly one-liners like the following: pelfCreator -m "xplshn" -n "org.chromium.Chromium" -p "chromium" -e "chromium.desktop", when they include a -e that ends in .desktop, that means that the produced AppBundle will have an icon & desktop file. (if you don't like this automatic method of building/doing things, you can use the pelf-dwfs tool to create AppBundles of any AppDir, or the bs2appbundle tool to convert conty-based AppImages to AppBundle and it also supports normal AppImages.)

Anyhow. I'm open to suggestions :)

Originally posted by @xplshn in https://github.com/ivan-hc/AM/issues/1079#issuecomment-2462867511

ivan-hc commented 1 week ago

@xplshn @Azathothas and @Samueru-sama , with participation request of @ruanformigoni , welcome everyone.

Please read carefully what I am about to tell you.

Now that the 9.1 release supports Toolpacks, it is good to explain how they are installed with "AM". This is the function that is used:

    if echo "$arg" | grep -q "appimage$"; then
        curl -Ls "$AMREPO"/templates/AM-SAMPLE-AppImage > "$CACHEDIR/toolpack/$arg.toolpack" || exit 1
    else
        curl -Ls "$AMREPO"/templates/AM-SAMPLE-Archive > "$CACHEDIR/toolpack/$arg.toolpack" || exit 1
    fi
    sed -i "s#APP=SAMPLE#APP=$arg#g; s#FUNCTION#$toolpack_version#g; s#wget \"\$version\"#wget \$($toolpak_url)#g" "$CACHEDIR/toolpack/$arg.toolpack"
    sed -e '/\[ -e/ s/^#*/#/' -i "$CACHEDIR/toolpack/$arg.toolpack" 2>/dev/null

as you can see, an if/fi statement is used to check which of the two patterns should be used to create the on-the-fly installation script.

Well, the scripts (authored by @Samueru-sama) if you look closely, are pretty much identical:

what changes is the final part. The AppImage script ends with this:

# LAUNCHER & ICON
./"$APP" --appimage-extract *.desktop 1>/dev/null && mv ./squashfs-root/*.desktop ./"$APP".desktop
./"$APP" --appimage-extract .DirIcon 1>/dev/null && mv ./squashfs-root/.DirIcon ./DirIcon
COUNT=0
while [ "$COUNT" -lt 10 ]; do # Tries to get the actual icon/desktop if it is a symlink to another symlink
    if [ -L ./"$APP".desktop ]; then
        LINKPATH="$(readlink ./"$APP".desktop | sed 's|^\./||' 2>/dev/null)"
        ./"$APP" --appimage-extract "$LINKPATH" 1>/dev/null && mv ./squashfs-root/"$LINKPATH" ./"$APP".desktop
    fi
    if [ -L ./DirIcon ]; then
        LINKPATH="$(readlink ./DirIcon | sed 's|^\./||' 2>/dev/null)"
        ./"$APP" --appimage-extract "$LINKPATH" 1>/dev/null && mv ./squashfs-root/"$LINKPATH" ./DirIcon
    fi
    [ ! -L ./"$APP".desktop ] && [ ! -L ./DirIcon ] && break
    COUNT=$((COUNT + 1))
done
sed -i "s#Exec=[^ ]*#Exec=$APP#g; s#Icon=.*#Icon=/opt/$APP/icons/$APP#g" ./"$APP".desktop
mv ./"$APP".desktop /usr/local/share/applications/"$APP"-AM.desktop && mv ./DirIcon ./icons/"$APP" 1>/dev/null
rm -R -f ./squashfs-root

...the other script has nothing, as it is meant to be completed via the -t option asking the user to add a URL to an icon and create a .desktop file.

Why am I telling you this?

If you want, the Archives script can also be used for AppImages, with the only difference that that piece should be added at the end.

If the script is not unique it is because of the creation of an AM-updater file for updates that contains additional steps, but that's another story.

What interests us is that it is possible to use a HEREDOC to add at the end of the file the necessary functions to extract/create icons and launchers. And all this "on the fly"! Just like it happens with the new Toolpacks implementation, in the new "AM" 9.1.

That said, keep in mind that little piece I posted here, and made by @Samueru-sama, in the AppImage scripts, and try to adapt it to AppBundle and FlatImage.

You will have a much better integration of apps installed via Toolpacks or other repositories that you will want to implement in the future.

Senza titolo

Samueru-sama commented 1 week ago

AppBundle could just implement --appimage-extract and make it much easier for us.

xplshn commented 1 week ago

AppBundle could just implement --appimage-extract and make it much easier for us.

I don't want to keep compatibility with bugs and end up writting Xorg but in shell. If such a compatibility option were to be added, it'd have to use squashfs-root, but that'd be misleading because we use DWARFS, we don't use SQUASHFS.

I'll invest some time, hopefully tomorrow, to test AM and try and integrate my format to it.

Samueru-sama commented 1 week ago

I don't want to keep compatibility with bugs and end up writting Xorg but in shell. If such a compatibility option were to be added, it'd have to use squashfs-root, but that'd be misleading because we use DWARFS, we don't use SQUASHFS.

You can just make a squashfs-root symlink, which is what the uruntime does already.

This is linux where /usr no longer means user and where the X in XDG no longer means X11.

Azathothas commented 1 week ago

It's best if we stop attributing other formats to be similar to Appimages. They aren't. Otherwise they would just be Appimage variant like NixAppImage is.

Each format is its own thing, and deserves the extra code that would be needed to be written to integrate that format. Be it running--pbundle_iconPng etc for AppBundles, or having to create a desktop.json and fetching icon remotely for flatimage, These need to be handled by their own respective integrator function.

There's going to be more and more of these formats in the future, and not all of them will be easy as Appimage or hard (unless @ruanformigoni adds a way to embed the desktop.json and icon files directly within the flatimage at creation time) as flatimage. There's also going to be self extracting portable archives, for which you would have to download/create the desktop/icon files manually.

The current way of extracting DirIcon, desktop will have to be changed for any script that aims to install/integrate based on the specific format. So there's no general solution that fits all, unless ofc AM wants to rely on pkgforge, which does offer downloadable desktop/icon files for all packages that are added, but I don't think that's the preferred choice.

ivan-hc commented 1 week ago

@Azathothas In truth, I know practically nothing about AppBundle and FlatImage, but I find them very interesting.

If it is possible to extract in any way an icon and a .desktop file from the bundle (or script, I have seen the content of an AppBundle) then I can dedicate a function in AppImage style that however uses the commands for AppBundle. Nothing simpler. In fact... if it were necessary to download such files from external sources, it would be good to add additional columns to the file you provided, in which there are the URLs to the icon and the .desktop file.

We can do whatever you want, just tell me how to do these things, and the Archive script will be compiled on the fly.

xplshn commented 1 week ago

I forked and made a simple modification to the AppImage template, its however, not yet tested. I've yet to fire up a container and change the rest of the code, in theory, integrating AppBundles is much easier than AppImages, since a flag is specifically provided to extract the icon, the desktop file, and etc, and you can even do all of these at once if you use --pbundle_link sh -c "cp \$SELF_TEMPDIR/.DirIcon ./DirIcon ; \$SELF_TEMPDIR/*.desktop .", wilder things can be done, but just those flags do everything we need.

Also, for actual integration, there's a program named pelfd that doubles as a daemon, but can also be used as a simple CLI command to integrate a specific AppBundle OR AppImage (yes, it supports both)

Anyways, I'll spin up a container, set up AM (since I don't have most of the deps of AM installed, and don't plan to use apk to install stuff like bash on my system), and then test if the template works.

ivan-hc commented 1 week ago

hey folks, the template provided by @xplshn works! https://github.com/ivan-hc/AM/pull/1103

ivan-hc commented 1 week ago

merged!

https://github.com/user-attachments/assets/5b73c3eb-7716-42c9-8ccd-aff7d774f81d

Istantanea_2024-11-12_02-44-27 png

ivan-hc commented 1 week ago

@ruanformigoni as you can see in my previous comment, I was able to handle AppBundles thanks to the template that @xplshn has provided here https://github.com/ivan-hc/AM/pull/1102 and in my test the app is 100% integrated

Basically, the differences between

...and...

is this, for AppImages the end of the script is this

# LAUNCHER & ICON
./"$APP" --appimage-extract *.desktop 1>/dev/null && mv ./squashfs-root/*.desktop ./"$APP".desktop
./"$APP" --appimage-extract .DirIcon 1>/dev/null && mv ./squashfs-root/.DirIcon ./DirIcon
COUNT=0
while [ "$COUNT" -lt 10 ]; do # Tries to get the actual icon/desktop if it is a symlink to another symlink
    if [ -L ./"$APP".desktop ]; then
        LINKPATH="$(readlink ./"$APP".desktop | sed 's|^\./||' 2>/dev/null)"
        ./"$APP" --appimage-extract "$LINKPATH" 1>/dev/null && mv ./squashfs-root/"$LINKPATH" ./"$APP".desktop
    fi
    if [ -L ./DirIcon ]; then
        LINKPATH="$(readlink ./DirIcon | sed 's|^\./||' 2>/dev/null)"
        ./"$APP" --appimage-extract "$LINKPATH" 1>/dev/null && mv ./squashfs-root/"$LINKPATH" ./DirIcon
    fi
    [ ! -L ./"$APP".desktop ] && [ ! -L ./DirIcon ] && break
    COUNT=$((COUNT + 1))
done
sed -i "s#Exec=[^ ]*#Exec=$APP#g; s#Icon=.*#Icon=/opt/$APP/icons/$APP#g" ./"$APP".desktop
mv ./"$APP".desktop /usr/local/share/applications/"$APP"-AM.desktop && mv ./DirIcon ./icons/"$APP" 1>/dev/null
rm -R -f ./squashfs-root

for AppBundles instead is this

# LAUNCHER & ICON
./"$APP" --pbundle_desktop | base64 -d > ./"$APP".desktop
./"$APP" --pbundle_pngIcon | base64 -d > ./DirIcon
sed -i "s#Exec=[^ ]*#Exec=$APP#g; s#Icon=.*#Icon=/opt/$APP/icons/$APP#g" ./"$APP".desktop
mv ./"$APP".desktop /usr/local/share/applications/"$APP"-AM.desktop && mv ./DirIcon ./icons/"$APP" 1>/dev/null

plus two extension references that change from ./tmp/*mage to ./tmp/*pp*undle... but the scripts are exactly the same.

In your case the tw extension references should change from ./tmp/*mage to ./tmp/*lat*mage (if the extension is "FlatImage"), that is the easier thing.

All we really need is the final step, to have the icon and the launcher.

Would you like to try?

ruanformigoni commented 1 week ago

Hello! Yes, I'll give it a shot.

ivan-hc commented 1 week ago

New release is out https://github.com/ivan-hc/AM/releases/tag/9.1.1

...I hope to improve support for these new package formats in the next release.

sandboiii commented 2 days ago

Hey, I was looking into Flatpak format, as many application developers prefer it over providing AppImages. There are some Flatpak applications I'd like to install with am (I don't like the Flatpak manager).

There's a discussion about the possibility of running Flatpak without installation. Someone has developed a Rust program that might achieve this.

Also, that discussion turned into another about repacking Flatpak into AppImage format (which could then be used in the conventional way). And another person has created a PoC script that does this conversion.

My technical knowledge isn't sufficient to fully grasp how these programs function. If you could somehow integrate Flatpak into am, it would be an incredible feature to have.

ivan-hc commented 2 days ago

hi @sandboiii , "AM" is "limited" to the installation of portable programs and is intended for portable programs.

But as you saw, through installation scripts and in the same way I approached AppBundle here, creating them on the fly, I could handle any other packaging format. It is enough to create a dedicated template, with creation of dedicated scripts for updating and removing into it.

However, I don't want to install or touch a single Flatpak on my system. I had them and used them time ego, even with pleasure to tell the truth... but they adopt an installation scheme that I had little opportunity to study, and that was enough for me to avoid them. It is difficult to completely remove them once installed. Years later I still had directories scattered throughout the system because of that model.

Here, I wrote "AM" specifically to avoid that model.

But if you were to think of creating a template like the ones already existing, I could consider an approach like the one in AppBundle. It's not a problem for me.

Samueru-sama commented 2 days ago

There's a https://github.com/flatpak/flatpak/issues/408 about the possibility of running Flatpak without installation.

I find it funny that probono commented that "Flatpak is optimized for other aspects, e.g., download size efficiency." when this is no longer the case, multiple flatpaks use different runtimes and the user is likely to end up with different runtimes and even different versions of the same runtime, and that explodes the storage usage of flatpak compared to appimage.

Also, that discussion turned into https://github.com/AppImage/AppImageKit/issues/297 about repacking Flatpak into AppImage format (which could then be used in the conventional way).

There is already NixAppImage which is very similar, and I think you can find every single app under the sun in nix.

xplshn commented 2 days ago

Nix is too fat, I made an alternative that generates AppDirs of any Alpine Linux package, but using it for arch is also trivial

ivan-hc commented 17 hours ago

Just added NixAppImage support https://github.com/ivan-hc/AM/commit/f12b5f4f5888bab18f61f8aa5ac3097815d7f826

ivan-hc commented 17 hours ago

Since there is just chromium.nixappimage in the list @Azathothas provided, I have tested this on it.

https://github.com/user-attachments/assets/d1d264b4-f4b0-45e0-a800-0afcbbc42053