35
36:- module(swish_version,
37 [ check_prolog_version/1, 38 prolog_version_atom/1, 39 register_git_module/2, 40 git_module_property/2, 41 git_update_versions/1 42 ]). 43:- use_module(library(option)). 44:- use_module(library(lists)). 45:- use_module(library(git)).
57:- multifile
58 git_module_hook/3.
68check_prolog_version(Required) :-
69 prolog_version_ok(Required),
70 !.
71check_prolog_version(Required) :-
72 throw(error(prolog_version_error(Required), _)).
73
74prolog_version_ok(or(V1, V2)) :-
75 !,
76 ( prolog_version_ok(V1)
77 -> true
78 ; prolog_version_ok(V2)
79 ).
80prolog_version_ok(Required) :-
81 current_prolog_flag(version, MyVersion),
82 MyVersion >= Required.
88prolog_version_atom(Version) :-
89 current_prolog_flag(version_git, Version),
90 !.
91prolog_version_atom(Version) :-
92 current_prolog_flag(version_data, swi(Major,Minor,Patch,Options)),
93 ( memberchk(tag(Tag), Options)
94 -> format(atom(Version), '~w.~w.~w-~w', [Major, Minor, Patch, Tag])
95 ; format(atom(Version), '~w.~w.~w', [Major, Minor, Patch])
96 ).
97
98
99
100:- multifile
101 prolog:message//1,
102 prolog:error_message//1. 103
104prolog:error_message(prolog_version_error(Required)) -->
105 { current_prolog_flag(version, MyVersion),
106 user_version(MyVersion, MyV),
107 user_version(Required, Req)
108 },
109 [ 'This program requires SWI-Prolog ~w'-[Req], nl,
110 'while you are running version ~w.'-[MyV], nl,
111 'Please visit http://www.swi-prolog.org and', nl,
112 'upgrade your version of SWI-Prolog.'
113 ].
114prolog:message(git(no_version)) -->
115 [ 'Sorry, cannot retrieve version stamp from GIT.' ].
116prolog:message(git(update_versions)) -->
117 [ 'Updating GIT version stamps in the background.' ].
118
119
120user_version(or(V1,V2), Version) :-
121 !,
122 user_version(V1, A1),
123 user_version(V2, A2),
124 format(atom(Version), '~w or ~w', [A1, A2]).
125user_version(N, Version) :-
126 Major is N // 10000,
127 Minor is (N // 100) mod 100,
128 Patch is N mod 100,
129 atomic_list_concat([Major, Minor, Patch], '.', Version).
130
131
132 135
136:- dynamic
137 git_module/3, 138 git_module_prop/3.
155register_git_module(Name, Options) :-
156 ( prolog_load_context(directory, BaseDir)
157 -> true
158 ; working_directory(BaseDir, BaseDir)
159 ),
160 select_option(directory(Dir), Options, RestOptions, '.'),
161 absolute_file_name(Dir, AbsDir,
162 [ file_type(directory),
163 relative_to(BaseDir),
164 access(read)
165 ]),
166 retractall(git_module(Name, _, _)),
167 assert(git_module(Name, AbsDir, RestOptions)).
168
169git_update_versions(Name) :-
170 catch(forall(current_git_module(Name, _, _),
171 update_version(Name)),
172 _,
173 print_message(warning, git(no_version))).
174
175update_version(Name) :-
176 current_git_module(Name, Dir, Options),
177 ( catch(git_describe(GitVersion, [directory(Dir)|Options]), _, fail)
178 -> true
179 ; GitVersion = unknown
180 ),
181 retractall(git_module_prop(Name, version, _)),
182 assert(git_module_prop(Name, version, GitVersion)).
183
184current_git_module(Name, Dir, Options) :-
185 git_module(Name, Dir, Options).
186current_git_module(Name, Dir, Options) :-
187 git_module_hook(Name, Dir, Options).
204git_module_property(Name, Property) :-
205 ( var(Name)
206 -> current_git_module(Name, _, _),
207 git_module_property(Name, Property)
208 ; compound(Property)
209 -> once(gen_module_property(Name, Property))
210 ; gen_module_property(Name, Property)
211 ).
212
213gen_module_property(Name, version(Version)) :-
214 ( git_module_prop(Name, version, Version0)
215 -> true
216 ; git_update_versions(Name),
217 git_module_prop(Name, version, Version0)
218 ),
219 Version0 \== unknown,
220 Version = Version0.
221gen_module_property(Name, directory(Dir)) :-
222 current_git_module(Name, Dir, _).
223gen_module_property(Name, remote(Alias, Remote)) :-
224 ( ground(Alias)
225 -> true
226 ; Alias = origin
227 ),
228 current_git_module(Name, Dir, _),
229 ( git_module_prop(Name, remote, Alias-Remote)
230 -> true
231 ; git_remote_url(Alias, Remote, [directory(Dir)]),
232 asserta(git_module_prop(Name, remote, Alias-Remote))
233 ).
234gen_module_property(Name, Term) :-
235 current_git_module(Name, _, Options),
236 member(Term, Options).
237
238
239
240 243
244bg_git_update_versions :-
245 print_message(informational, git(update_versions)),
246 thread_create(git_update_versions(_), _,
247 [ detached(true)
248 ]).
249
250:- multifile
251 user:message_hook/3. 252
253user:message_hook(make(done(_)), _, _) :-
254 bg_git_update_versions,
255 fail.
256
258:- if(current_predicate(http_unix_daemon:http_daemon/0)). 259:- initialization git_update_versions(_). 260:- else. 261:- initialization bg_git_update_versions. 262:- endif.
Manage software versions
The module deals with software versions. It currently implements two features: test whether SWI-Prolog is sufficiently new using check_prolog_version/1 and find GIT version signatures for the running server. Modules that want their version info available through the web-page can do so using a call to register_git_module/2. */