Trying to do a pack_install on a new Mac laptop with no Apple developer tools installed, e.g.,
?- pack_install(clpBNR).
% Contacting server at https://www.swi-prolog.org/pack/query ... ok
Installation plan:
Install clpBNR at version 0.12.2 from https://github.com/ridgeworks/clpBNR.git (downloaded 3,670 times)
Download packs? Y/n?
xcode-select: note: No developer tools were found, requesting install.
% If developer tools are located at a non-default location on disk, use `sudo xcode-select --switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools, and cancel the installation dialog.
% See `man xcode-select` for more details.
ERROR: Process "process(path(git),[clone,https://github.com/ridgeworks/clpBNR.git,/Users/rickworkman/.local/share/swi-prolog/pack/clpBNR])": exit status: 1
...
Is there some (undocumented?) dependancy on Apple developer tools to install a pack?
Some packs also require make or cmake – this dependency (and also the “build steps”) isn’t terribly well documented. (Assuming that make is part of Xcode.) Pack installation uses the build library that allows various “make”-like plugins, and it might be looking for something that requires Xcode?
(I don’t understand many of the details of installing packs, so I’ve been reading the code to improve its documentation, but haven’t got very far.)
Following up: this has something to do with loading from a git repo. If I use a URL of an archived version, it works:
?- pack_install('https://github.com/ridgeworks/clpBNR/archive/refs/tags/v0.12.1.zip').
Installation plan:
Install clpBNR at version 0.12.1 from https://github.com/ridgeworks/clpBNR/archive/refs/tags/v0.12.1.zip
Download packs? Y/n?
% Downloading clpBNR ... 2,405,133 bytes
% Contacting server at https://www.swi-prolog.org/pack/query ... ok
true.
?- [library(clpBNR)].
% *** clpBNR v0.12.1 ***.
% Arithmetic global flags will be set to prefer rationals and IEEE continuation values.
true.
Installing from a git repo uses git to download the pack. Actually, AFAIK, it checks that git is a known executable and then uses git. Otherwise, for known git servers (only github I think for now), it downloads the files as tar archive. But, MacOS seems to have a dummy git executable that triggers activating Xcode There is a finite amount of weird environments we can handle …
This has been fixed for newer Mac OS version but some years ago I still regularly experienced a problem with git every time the OS got an update. There is this rant from some years back, the message is that I periodically had to run
$ xcode-select --install
to fix git among other things. I had installed git with homebrew.
% git -help
xcode-select: note: No developer tools were found, requesting install.
If developer tools are located at a non-default location on disk, use `sudo xcode-select --switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools, and cancel the installation dialog.
See `man xcode-select` for more details.
%
From the xcode-select man page:
--install
Opens a user interface dialog to request automatic installation
of the command line developer tools.
So the answer is yes, the package manager on Mac’s does have a dependancy on the MacOS developer tools. I think this applies in general though, i.e., some level of git support must be available on the platform to install packs from git repos. Perhaps that support requirement could be more clearly be described in the package manager documentation somewhere.
As most people do not read the docs and it is hard to keep them in sync with the implementation, I guess a good error message is as good as it gets. Normally, I think it will raise an existence error for source_sinkpath(git). That can probably be improved a little. Few people will interpret this correctly. In any case, if there is a program called git that does something different, it gets hard
That’s usually an issue and can a good error message be produced when there is a dummy git? Currently you get:
ERROR: Process "process(path(git),[clone,https://github.com/ridgeworks/clpBNR.git,/Users/rickworkman/.local/share/swi-prolog/pack/clpBNR])": exit status: 1
Here pointing to process(path(git), ... doesn’t help a lot either, i.e., what’s the root cause?
Maybe a better git check would also help, e.g., at least ensuring that git --version returned a sensible answer. (Intentional dummy commands tend to just provide hints for the user.)
For the docs, I was thinking that a general statement indicating that git support (i.e., the git command must be findable?) is a requirement would at least point users at the root cause, even if directly address the MacOS issue. (IMO people tend to read the docs much more carefully when error messages aren’t helpful.)
On a Mac you never know. They have gcc, which is just an alias for clang. True, it works most of the time, but it is not gcc. They have libreadline, which is just a wrapper around libedit that is far from a complete libreadline, etc.
As far as I’m concerned this as it is. If it is resolved in the latest MacOS it will die away as an issue. Before, Google can find this and I think an LLM can tell you what is wrong They are fairly good in explaining error reports in my experience …
Note that you not need git for installing github hosted packs. You only should not have a broken git. I’ll accept a PR that verifies that git is sane.
This succeeds or fails silently depending on whether the git --version command generates an error. Seems to do the right thing on systems with the dummy git and an operational git. In particular it can install packs on MacOS without requiring any developer tools.
Unless there are suggestions for improving this, I’ll generate a PR.
The test above (Does “git --version” result in a non-zero exit code?) has the intended effect when loading SWIP packs. However running the imposter git has an undesirable side effect (IMO) of a nagging MacOS dialog directing the user to download the Xcode command line tools.
So an alternative proposal:
have_git :-
process_which(path(git), _),
catch(run_process(path(man),['-w', 'git'],[output(_),error(_)]), % silent
error(Err,_),
\+ Err = process_error(_,_) % will succeed if no 'man' command
).
have_git now succeeds if there is a findable git command and a man page. This has the desired effect on MacOS without the “nag” since the test does not actually require the (possibly imposter) git command to be run.
I think this is platform agnostic. The findable command is the same as the current test and the man page test only fails when a man command exists and the git man page does not.
Comments welcome.
P.S.
Begs the question of why the git command is used at all?
Using git for git package URLs works reliably on any git repo. How to download a snapshot as.(tar) archive using HTTP varies between installations (if possible at all).
Then, updating the package when cloned as git repo is cheaper and you can use git to jump between versions, examine changes, prepare local changes and create a PR, etc. I think it would be a good idea to use git for all packages as it is simply more controlled. When downloaded from one of the main services, there is also some amount of community and vulnerability tracking.
Just to be clear, I wasn’t suggesting that packs shouldn’t be served from git repos. I was only questioning whether library(prolog_pack) should use the local git command if it isn’t necessary to do so. Is there some other advantage, e.g., reliability or performance?
I think my previous message contains enough motivation. You can check out git_archive_url/3 in library(prolog_pack) to see how fragile the alternative is. That is only for github. There is AFAIK no general alternative for using a git client. We can of course bundle a git client with SWI-Prolog, but that seems overkill.
“fragile” is a subjective term but from the doc:
%! git_archive_url(+URL, -Archive, +Options) is semidet.
%
% If we do not have git installed, some git services offer downloading
% the code as an archive using HTTP. This predicate makes this
% translation.
So it sounds like using the git command will work with a potentially broader range of repos and I guess that’s a good enough reason.
EDIT: Yes I now see your point - git_archive_url/3 only succeeds with github.com.
And worse, the implementation assumes various details on translating the git repo path and even change the host from which to download. I think there is no guarantee this will stay like this forever. There is simply no official GIT API to do this .
The best option for not relying on git is probably to create a Prolog library embedding a git client library. That seems an overkill. We could also write a git client in Prolog . Actually, the logic to assemble and disassemble git objects is available in Prolog and used by the SWISH file store.