Open xaoseric opened 3 years ago
Verified that parsing of .desktop files works as well.
And one showing a Discord appimage working properly
Thanks @xaoseric.
Shouldn't we also parse the Name=
key and make it possible to e.g., launch Discord
even though the file name is Discord-3.1.0alpha3.git-hf876-x86_64.AppImage
? No one wants to type Discord-3.1.0alpha3.git-hf876-x86_64
. Then the question is, if there is Discord-3.1.0alpha3.git-hf876-x86_64.AppImage
and Discord-3.2.0beta4_x86_64.AppImage
, which one should be started by launch Discord
? The one with the greater version, as in the (optional) X-AppImage-Version
key in the .desktop
file.
Ideally the Exec= which we parse in .desktop files would point to the correct executable. Looking for Name= and X-AppImage-Version= in .desktop could be a good option if it has a "-" in it, the goal was to get it working with Discord.AppImage for the moment so we can go back and add to it later.
The best solution would be a multi platform app store that could download .AppImage, .app and .AppDir files automatically and keep them updated in /Applications, /System and /Library.
One small bug I did find is that if we do launch PyCharm CE it says that it can't find PyCharm. We need to do launch "PyCharm CE" for it to find that .app directory.
Ideally the Exec= which we parse in .desktop files would point to the correct executable.
This is not how AppImage works. What do you mean by "the correct executable"? The "correct executable" is the AppImage itself.
"TODO: Parse it for Exec="
Why do you want to do that? This key has no useful information for how the AppImage should be launched. Only the path to the AppImage is needed for that.
if (file.fileName() == firstArg + ".desktop")
I think this is not what we should be checking for. Instead, we should be checking whether Name=
matches.
Example:
launch Discord
should check if we have Name=Discord
in the desktop file. If yes, then it is a candidate.
But to check this, we would need to have a way to peek inside the AppImage to read the desktiop file, wouldn't we?
"TODO: Parse it for Exec="
Why do you want to do that? This key has no useful information for how the AppImage should be launched. Only the path to the AppImage is needed for that.
Exec= points to the executble which allows none .app, .AppDir and .AppImage files to work ex: for Firefox it points to /usr/local/bin/firefox and it was what was in the todo notes before since we already check for the .AppImage extension before checking if a .desktop is a candidate.
if (file.fileName() == firstArg + ".desktop")
I think this is not what we should be checking for. Instead, we should be checking whether
Name=
matches.Example:
launch Discord
should check if we have
Name=Discord
in the desktop file. If yes, then it is a candidate.But to check this, we would need to have a way to peek inside the AppImage to read the desktiop file, wouldn't we?
Yes, we should also check that Name= also matches if the .desktop matches which at this point in parsing .desktop files, we are just parsing those directly so no need to look inside of any file.
As far as looking inside the AppImage, we could use libappimage to do that or we implement our own way of doing that which I think would probably be further down the line once we get the core functionality of it working we can go back and add in additional features like that.
https://docs.appimage.org/api/libappimage/
As it is on Linux, as long as it is executable, we don’t have to do anything on our end unless we want to check the .desktop file in the .AppImage.
For FreeBSD however, that is another matter: https://forums.freebsd.org/threads/appimage-support.75097/
Exec= points to the executble which allows none .app, .AppDir and .AppImage files to work
I think you don't understand how AppImages work. To launch an AppImage, you need to use the path to the AppImage, whereas the Exec=
key contains the name and arguments of the executable that in turn get used inside the AppImage (if the AppRun
in that particular AppImage uses this information at all).
So, to launch an AppImage from the outside world, all you need to know is the path to the AppImage.
My objective is to do away with .desktop
files altogether.
Shouldn't we also parse the Name= key and make it possible to e.g., launch Discord even though the file name is Discord-3.1.0alpha3.git-hf876-x86_64.AppImage? No one wants to type Discord-3.1.0alpha3.git-hf876-x86_64.
So thinking about it again maybe we could do something much simpler which would cover at least >80% of cases:
.AppImage
suffix-
characters in the filename, remove everything behind the second-last -
character from the filename-
character in the filename, remove everything behind the -
_
with
-
characters in the filename, assume that what is between the first and second -
is the version; this will be needed to decide amongst several candidates (to pick the latest version)Result:
launch Discord
would work with, e.g.,
Discord-1.3.0beta1-x86_64.AppImage
Discord-1.3.0beta1.AppImage
Discord.AppImage
But it would fail on
Discord-1.3.0-beta1-x86_64.AppImage
launch "Discord Beta"
would work with, e.g.,
Discord_Beta-1.3.0beta1-x86_64.AppImage
Discord_Beta-1.3.0beta1.AppImage
Discord_Beta.AppImage
But it would fail on
Discord_Beta-1.3.0-beta1-x86_64.AppImage
I think you don't understand how AppImages work. To launch an AppImage, you need to use the path to the AppImage, whereas the Exec= key contains the name and arguments of the executable that in turn get used inside the AppImage (if the AppRun in that particular AppImage uses this information at all).
A .AppImage is an executable on Linux. Quoting the faq from the docs. https://docs.appimage.org/user-guide/faq.html#question-how-do-i-run-an-appimage
How do I run an AppImage? Make it executable and double-click it.
So what we would need to do is check if we are running on BSD or Linux, if it is running on a BSD based system we can than implement any compatibility that needs to be done to make it work.
According the AppImage spec repo, there is an AppRun
contained in the root of the filesystem image, supporting type 2 onward would make the most sense.
https://github.com/AppImage/AppImageSpec/blob/master/draft.md#type-2-image-format
So thinking about it again maybe we could do something much simpler which would cover at least >80% of cases:
- Look for files with the .AppImage suffix
- If there are at least 2 - characters in the filename, remove everything behind the second-last - character from the filename
- there is only one - character in the filename, remove everything behind the -
- Replace _ with
- Compare the result against what the user wants to launch to determine whether we have a candidate
- If there are at least 2 - characters in the filename, assume that what is between the first and second - is the version; this will be needed to decide amongst several candidates (to pick the latest version)
Yes, that is a good idea, that can be a feature enhancement further on down the line now that we know we have something that is working.
Opened an issue referencing the improvements for the AppImage handling so we can get this merged in and discuss how we want to improve it in that issue.
So what we would need to do is check if we are running on BSD or Linux, if it is running on a BSD based system we can than implement any compatibility that needs to be done to make it work.
Yes, that is being discussed at https://github.com/AppImage/AppImageKit/issues/98. But that whole topic is more complex. Don't worry about Linux AppImages on FreeBSD yet. Work is underway.
Let's make this issue here only about finding and launching the correct AppImage.
So thinking about it again maybe we could do something much simpler which would cover at least >80% of cases: (...)
Yes, that is a good idea, that can be a feature enhancement further on down the line
Do you think you can make it part of this PR?
Do you think you can make it part of this PR?
Yes, certainly will try.
@probonopd the PR now supports the changes as requested.
Thank you very much. Looks promising. However I am running into a segfault. I created three files with this content and made them executable:
#!/bin/sh
echo "This works" > /dev/stderr
exit 1
~/Applications/Test.AppImage
~/Applications/Test-2.0.AppImage
~/home/user/Applications/Test-3.0.AppImage
Then ran:
% ./launch Test
# Found "/home/user/Applications/Test-3.0.AppImage"
# Found "/home/user/Applications/Test.AppImage"
# Found "/home/user/Applications/Test-2.0.AppImage"
(...)
Took 16 milliseconds to find candidates via the filesystem
Candidates: (QFileInfo(/home/user/Applications/Test-3.0.AppImage), QFileInfo(/home/user/Applications/Test.AppImage), QFileInfo(/home/user/Applications/Test-2.0.AppImage))
0
zsh: segmentation fault ./launch Test
Possibly it doesn't know what to do when some candidates have a version and some don't. In those situations, it should use the one with the highest version number, in this example ~/home/user/Applications/Test-3.0.AppImage
.
Awesome, so it is getting closer to being on the right track then, once we get it working, the same concept should work for .app and .AppDir files. You could probably merge the stuff into a develop branch so that way the changes don't affect the stable main branch, and once there is enough changes to warrant a new release, we can merge into the master. Next thing we probably will want to do is create some type of database for keeping track of the available apps so doing say "launch --scan" would scan the system for available apps and add them to a database.
% ./launch Test
# Descending into "/Applications/Developer"
# Descending into "/Applications/Video"
# Descending into "/Applications/Autostart"
# Descending into "/Applications/Preferences"
# Descending into "/Applications/Graphics"
# Descending into "/Applications/Games"
# Descending into "/Applications/Utilities"
# Descending into "/Applications/Audio"
# Descending into "/Applications/Developer Preview"
# Descending into "/Applications/3D Printing"
Took 17 milliseconds to find candidates via the filesystem
Candidates: ()
% LANG=C ls -lh ~/Applications/Test*
-rwxr-xr-x 1 user user 50B Mar 15 19:54 /home/user/Applications/Test-2.0.AppImage
-rwxr-xr-x 1 user user 50B Mar 15 19:54 /home/user/Applications/Test-3.0.AppImage
-rwxr-xr-x 1 user user 50B Mar 15 19:54 /home/user/Applications/Test.AppImage
% cat /home/user/Applications/Test.AppImage
#!/bin/sh
echo "This works" > /dev/stderr
exit 1
Why does it not find them?
@probonopd reverted back to old if statement, should be fixed now.
Hello @xaoseric, it now identifies the candidates correctly but segfaults while trying to decide which one to use:
FreeBSD% ./launch Test
# Found "/home/user/Applications/Test-2.0.AppImage"
# Found "/home/user/Applications/Test.AppImage"
# Found "/home/user/Applications/Test-3.0.AppImage"
# Descending into "/Applications/Video"
# Descending into "/Applications/Developer"
# Descending into "/Applications/Autostart"
# Descending into "/Applications/3D Printing"
# Descending into "/Applications/Utilities"
# Descending into "/Applications/Audio"
# Descending into "/Applications/Office"
# Descending into "/Applications/Developer Preview"
# Descending into "/Applications/Preferences"
# Descending into "/Applications/Graphics"
Took 13 milliseconds to find candidates via the filesystem
Candidates: (QFileInfo(/home/user/Applications/Test-2.0.AppImage), QFileInfo(/home/user/Applications/Test.AppImage), QFileInfo(/home/user/Applications/Test-3.0.AppImage))
QFileInfo(/home/user/Applications/Test-2.0.AppImage)
0
zsh: segmentation fault ./launch Test
Note that in my case /home/user/Applications/Test-2.0.AppImage
is not really an AppImage, but I doubt it would make any difference?
FreeBSD% file /home/user/Applications/Test-2.0.AppImage
/home/user/Applications/Test-2.0.AppImage: POSIX shell script, ASCII text executable
The expected behavior would be that it recognizes that 3.0 is the highest version number among the three candidates and hence selects that candidate.
Odd, it correctly identifies the new version on my linux setup, could it be a difference between BSD and Linux in the way that Qt handles things?
Possible. Any way you could download a helloSystem ISO and test it there?
I'll be setting up a test system with helloSystem this weekend.
Hello @xaoseric how did your tests go?
Adds support for .AppImage files and parses .desktop files with QSettings