View source with raw comments or as raw
    1/*  Part of SWISH
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@cs.vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (C): 2018, VU University Amsterdam
    7			 CWI Amsterdam
    8    All rights reserved.
    9
   10    Redistribution and use in source and binary forms, with or without
   11    modification, are permitted provided that the following conditions
   12    are met:
   13
   14    1. Redistributions of source code must retain the above copyright
   15       notice, this list of conditions and the following disclaimer.
   16
   17    2. Redistributions in binary form must reproduce the above copyright
   18       notice, this list of conditions and the following disclaimer in
   19       the documentation and/or other materials provided with the
   20       distribution.
   21
   22    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   23    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   24    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   25    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   26    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   27    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   28    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   30    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   32    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   33    POSSIBILITY OF SUCH DAMAGE.
   34*/
   35
   36:- module(swish_version_service, []).   37:- use_module(library(http/http_dispatch)).   38:- use_module(library(http/http_json)).   39:- use_module(library(http/http_parameters)).   40:- use_module(library(http/html_write)).   41:- use_module(library(git)).   42:- use_module(library(apply)).   43
   44:- use_module(version).   45:- use_module(markdown).

Serve version details over HTTP

This module serves SWISH and Prolog version details over HTTP. This is file is normally loaded though the config file version_info.pl. This file is not loaded by default for security reasons. */

   54:- http_handler(swish(versions),  versions,  [id(versions)]).   55:- http_handler(swish(changes),   changes,   [id(changes)]).   56:- http_handler(swish(changelog), changelog, [id(changelog)]).   57
   58versions(_Request) :-
   59    prolog_version_atom(SWIVersion),
   60    module_version_data(swish, SWISHVersion),
   61    reply_json_dict(json{ prolog:
   62                          json{ brand:  "SWI-Prolog",
   63                                version: SWIVersion
   64                              },
   65                          swish:SWISHVersion
   66                        }).
   67
   68module_version_data(Module, Dict) :-
   69    findall(Name-Value, module_version_data(Module, Name, Value), Pairs),
   70    dict_pairs(Dict, json, Pairs).
   71
   72module_version_data(Module, Name, Value) :-
   73    git_module_property(Module, Term),
   74    Term =.. [Name,Value].
 changes(+Request)
Get quick statistics on changes since a commit to inform the user about new functionality. If no commit is passed we reply no changes and the last commit we have seen.
   82:- dynamic  change_cache/3.   83:- volatile change_cache/3.   84
   85:- multifile
   86    user:message_hook/3.   87
   88user:message_hook(make(done(_)), _, _) :-
   89    retractall(change_cache(_,_,_)),
   90    fail.
   91
   92changes(Request) :-
   93    http_parameters(Request,
   94                    [ commit(Commit, [default(last)]),
   95                      show(Show, [oneof([tagged, all]), default(tagged)])
   96                    ]),
   97    changes(Commit, Show, Changes),
   98    reply_json_dict(Changes).
   99
  100changes(Commit, Show, Changes) :-
  101    change_cache(Commit, Show, Changes),
  102    !.
  103changes(Commit, Show, Changes) :-
  104    changes_nc(Commit, Show, Changes),
  105    asserta(change_cache(Commit, Show, Changes)).
  106
  107changes_nc(Commit, Show, Changes) :-
  108    Commit \== last,
  109    git_module_property(swish, directory(Dir)),
  110    atom_concat(Commit, '..', Revisions),
  111    git_shortlog(Dir, ShortLog, [ revisions(Revisions) ]),
  112    last_change(ShortLog, LastCommit, LastModified),
  113    !,
  114    include(filter_change(Show), ShortLog, ShowLog),
  115    length(ShowLog, Count),
  116    Changes = json{ commit:  LastCommit,
  117                    date:    LastModified,
  118                    changes: Count
  119                  }.
  120changes_nc(_, _Show, Changes) :-
  121    git_module_property(swish, directory(Dir)),
  122    git_shortlog(Dir, ShortLog, [limit(1)]),
  123    last_change(ShortLog, LastCommit, LastModified),
  124    !,
  125    Changes = json{ commit:  LastCommit,
  126                    date:    LastModified,
  127                    changes: 0
  128                  }.
  129changes_nc(_Commit, _Show, Changes) :-
  130    Changes = json{ changes: 0
  131                  }.
  132
  133
  134last_change([LastEntry|_], LastCommit, LastModified) :-
  135    git_log_data(commit_hash,         LastEntry, LastCommit),
  136    git_log_data(committer_date_unix, LastEntry, LastModified).
  137
  138filter_change(all, _Change).
  139filter_change(tagged, Change) :-
  140    git_log_data(subject, Change, Message0),
  141    sub_string(Message0, Pre, _, _, ":"),
  142    Pre > 0,
  143    !,
  144    sub_string(Message0, 0, Pre, _, Tag),
  145    string_upper(Tag, Tag).
 changelog(+Request)
Sends the changelog since a given version, as well as the last commit and its timestamp.
  152changelog(Request) :-
  153    http_parameters(Request,
  154                    [ commit(Since, [optional(true)]),
  155                      last(Count, [default(10)]),
  156                      show(Show, [oneof([tagged, all]), default(tagged)])
  157                    ]),
  158    git_module_property(swish, directory(Dir)),
  159    (   nonvar(Since)
  160    ->  atom_concat(Since, '..', Revisions),
  161        Options = [ revisions(Revisions) ]
  162    ;   Options = [ limit(Count) ]
  163    ),
  164    git_shortlog(Dir, ShortLog, Options),
  165    (   ShortLog = [LastEntry|_]
  166    ->  git_log_data(commit_hash,         LastEntry, LastCommit),
  167        git_log_data(committer_date_unix, LastEntry, LastModified),
  168        convlist(changelog(Show), ShortLog, ChangeLog),
  169        reply_json_dict(json{ commit:    LastCommit,
  170                              date:	 LastModified,
  171                              changelog: ChangeLog
  172                            })
  173    ;   reply_json_dict(json{ message: "No changes"
  174                            })
  175    ).
  176
  177changelog(Show, Entry,
  178          json{commit:Commit,
  179               author: Author,
  180               committer_date_relative: When,
  181               message: Message}) :-
  182    git_log_data(subject, Entry, Message0),
  183    format_commit_message(Show, Message0, Message),
  184    git_log_data(commit_hash, Entry, Commit),
  185    git_log_data(author_name, Entry, Author),
  186    git_log_data(committer_date_relative, Entry, When).
  187
  188
  189format_commit_message(tagged, Message0, Message) :-
  190    sub_string(Message0, Pre, _, Post, ":"),
  191    Pre > 0,
  192    !,
  193    sub_string(Message0, 0, Pre, _, Tag),
  194    string_upper(Tag, Tag),
  195    sub_string(Message0, _, Post, 0, Msg),
  196    string_codes(Msg, Codes),
  197    wiki_file_codes_to_dom(Codes, '/', DOM),
  198    phrase(wiki_html(div(class('v-changelog-entry'),
  199                         [ span(class('v-changelog-tag'), Tag)
  200                         | DOM
  201                         ])),
  202           Tokens),
  203    with_output_to(string(Message), print_html(Tokens)).
  204format_commit_message(all, Message0, Message) :-
  205    format_commit_message(tagged, Message0, Message),
  206    !.
  207format_commit_message(all, Message0, Message) :-
  208    string_codes(Message0, Codes),
  209    wiki_file_codes_to_dom(Codes, '/', DOM),
  210    phrase(wiki_html(div(class('v-changelog-entry'),
  211                         DOM)),
  212           Tokens),
  213    with_output_to(string(Message), print_html(Tokens)).
  214
  215		 /*******************************
  216		 *          COMPATIBILITY	*
  217		 *******************************/
  218
  219% support SWI-Prolog < 7.7.19
  220
  221:- if(\+catch(check_predicate_option(git:git_shortlog/3, 3, revisions(a)),
  222              error(_,_), fail)).  223:- abolish(git:git_shortlog/3).  224git:(
  225git_shortlog(Dir, ShortLog, Options) :-
  226    (   option(revisions(Range), Options)
  227    ->  RangeSpec = [Range]
  228    ;   option(limit(Limit), Options, 10),
  229        RangeSpec = ['-n', Limit]
  230    ),
  231    (   option(git_path(Path), Options)
  232    ->  Extra = ['--', Path]
  233    ;   option(path(Path), Options)
  234    ->  relative_file_name(Path, Dir, RelPath),
  235        Extra = ['--', RelPath]
  236    ;   Extra = []
  237    ),
  238    git_format_string(git_log, Fields, Format),
  239    append([[log, Format], RangeSpec, Extra], GitArgv),
  240    git_process_output(GitArgv,
  241                       read_git_formatted(git_log, Fields, ShortLog),
  242                       [directory(Dir)])).
  243:- endif.