

Naming of file
Quite important indeed.
The code in library/prolog_pack.pl
reveals:
pack_install/2 will silently fail if the filename doesn't match expectations (that's probably an error, it should throw and tell the user what's going on), namely:
PACK-VERSION.EXT
PACK is a string consisting of:
- upper or lowercase letters A..Z a..z
- digits 0..9
- the underscore _
It is separated from the VERSION necessarily by a dash
If VERSION and the dash are missing then the URI https://www.swi-prolog.org/pack/query is queried for the file
(even if it looks like a real path and actually exists, which weirds me out).
VERSION is a string of dot-joined integers.
An arbitrary number of integers are allowed, they can also have leading digits which are disappeared as the string is transformed into its integer representation
(One should prolly go with a semantic versioning string string here)
EXT is the extension. It can be:
- Missing
tgz
,tar
,zip
,foo
It doesn't really matter! The extension may not even correspond to the archive format. The archive is opened with archive_open/4 and that's it.
Once opened, the loader looks for a specific file in the archive, namely pack.pl
, and throws if it doesn't find it. But there is a problem in the code...
Note that you cann put a pack .tgz on github and download it from there as you get the "raw file" only b clicking through a "download" button or by using an URL like:
https://github.com/dtonhofer/prolog_code/blob/main/packed/onepointfour_semver-0.9.tgz?raw=true
which pack_install/1 doesn't like.
Example
Suppose you want to create pack onepointfour_basics
.
Set up a file tree as follows:
onepointfour_basics toplevel dir named after your pack (must be unique, maybe named after your domain, as for Java?) ├── pack.pl the pack meta-information file, a Prolog program └── prolog Prolog source code in here ├── meta_helpers.pl ...content #1 ├── README.md ...content #2 ├── safe_format.pl ...content #3 ├── throwme_example.pl ...content #4 └── throwme.pl ...content #5
The directory prolog
will be put on swipl's library search path, so you probably do not want to have subdirectories underneath that.
Now create the tar file, named after the pack and with the version string as it appears in pack.pl:
$ tar czf onepointfour_basics-1.0.0.tgz onepointfour_basics/
Everything in the tar file is nicely under onepointfour_basics
as you can see by listing the tar file contents:
$ tar tf onepointfour_basics-1.0.0.tgz onepointfour_basics/ onepointfour_basics/prolog/ onepointfour_basics/prolog/README.md onepointfour_basics/prolog/throwme_example.pl onepointfour_basics/prolog/meta_helpers.pl onepointfour_basics/prolog/safe_format.pl onepointfour_basics/prolog/throwme.pl onepointfour_basics/pack.pl
You can now put the pack file where it is needed and install the pack from swipl with pack_install/1:
?- pack_install('onepointfour_basics-1.0.0.tgz'). true.
(which works under condition that file is in swipl's current directory or given as qualified filename; otherwise pack_install/1 tries to interprete the filename as an URL and a confusing error results)
After this, the file tree of the pack appears (on Linux) in
$HOME/.local/share/swi-prolog/pack/onepointfour_basics/
with the expected tree structure:
$ tree .local/share/swi-prolog/pack/onepointfour_basics/ .local/share/swi-prolog/pack/onepointfour_basics/ ├── pack.pl └── prolog ├── meta_helpers.pl ├── README.md ├── safe_format.pl ├── throwme_example.pl └── throwme.pl
Additionally, the prolog
directory is on the library search path:
?- file_search_path(library,X),atom(X),re_match("onepointfour",X). X = '/home/calvin/.local/share/swi-prolog/pack/onepointfour_basics/prolog' ; false.
So, assuming all of those files under prolog
are module files (they should be), just do:
?- use_module(library('meta_helpers.pl')), use_module(library('safe_format.pl')), use_module(library('throwme.pl')).
to make their predicates accessible. This also works without the quotes and the `.pl` but I like to be clear that a file is being loaded. If there is a subtree under prolog
, the paths given to use_module/1 have to be changed accordingly.
If the files contain proper pldoc documentation text, then starting the pldoc web server in swipl:
?- doc_server(4000). % Started server at http://localhost:4000/pldoc/ true.
and pointing the browser to
http://localhost:4000/pldoc/doc/_CWD_/index.html
will show the pack in the drop-list at the top of the page.
(but help/1 doesn't work for the packs).
You can "remove the pack" by issuing a pack_remove/1 call:
?- pack_remove(onepointfour)
this physically removes the pack directory from disk.