1:- module(
    2  ppm_git,
    3  [
    4    git_add_remote_uri/2,  % +Directory, +Uri
    5    git_checkout/2,        % +Directory, +TagOrVersion
    6    git_clone/2,           % +Directory, +Uri
    7    git_create_tag/2,      % +Directory, +Tag
    8    git_current_version/2, % +Directory, -Version
    9    git_delete_tag/2,      % +Directory, +Tag
   10    git_fetch/1,           % +Directory
   11    git_initial_push/1,    % +Directory
   12    git_remote_exists/1,   % +Uri
   13    git_remote_uri/2,      % +Directory, -Uri
   14    git_tag/2,             % +Directory, -Tag
   15    git_version/2,         % +Directory, -Version
   16    git_version_latest/2   % +Directory, -LatestVersion
   17  ]
   18).

Prolog Package Manager (PPM): Git support

Debug flag: `ppm(git)'.


author
- Wouter Beek
version
- 2017-2018 */
   30:- use_module(library(ansi_term)).   31:- use_module(library(debug)).   32:- use_module(library(git), []).   33
   34:- use_module(library(ppm_generic)).
 git_add_remote_uri(+Directory:atom, +Uri:atom) is det
   42git_add_remote_uri(Dir, Uri) :-
   43  git(Dir, [remote,add,origin,Uri]).
 git_checkout(+Directory:atom, +TagOrVersion:compound) is det
   49git_checkout(Dir, tag(Tag)) :- !,
   50  git(Dir, [checkout,'-b',Tag,Tag]).
   51git_checkout(Dir, version(Version)) :-
   52  atom_phrase(version(Version), Tag),
   53  git_checkout(Dir, tag(Tag)).
 git_clone(+Directory:atom, +Uri:atom) is det
   59git_clone(Dir, Uri) :-
   60  git(Dir, [clone,Uri]).
 git_create_tag(+Directory:atom, +Tag:atom) is det
   66git_create_tag(Dir, Tag) :-
   67  git_tag(Dir, Tag), !.
   68git_create_tag(Dir, Tag) :-
   69  git(Dir, [tag,'-a',Tag,'-m',Tag]),
   70  git(Dir, [push,origin,Tag]).
 git_current_version(+Directory:atom, -Version:compound) is det
   76git_current_version(Dir, Version) :-
   77  % Git returns error code 128 when there are no tags
   78  git(Dir, [describe,'--tags'], Codes),
   79  phrase(version(Version), Codes, _Rest).
 git_delete_tag(+Directory:atom, +Tag:atom) is det
   85git_delete_tag(Dir, Tag) :-
   86  git(Dir, [tag,'-d',Tag]),
   87  atom_concat(':refs/tags/', Tag, Arg),
   88  git(Dir, [push,origin,Arg]).
 git_fetch(+Directory:atom) is det
   94git_fetch(Dir) :-
   95  git(Dir, [fetch]).
 git_initial_push(+Directory:atom) is det
  101git_initial_push(Dir) :-
  102  git(Dir, [push,'-u',origin,master]).
 git_remote_exists(+Uri:atom) is semidet
Succeeds iff a Git repository is located at Uri.
  110git_remote_exists(Uri) :-
  111  git(['ls-remote',Uri]).
 git_remote_uri(+Directory:atom, -Uri:atom) is det
  117git_remote_uri(Dir, Uri) :-
  118  git(Dir, [config,'--get','remote.origin.url'], Codes),
  119  atom_codes(Atom, Codes),
  120  atom_concat(Uri, '\n', Atom).
 git_tag(+Directory:atom, +Tag:atom) is semidet
git_tag(+Directory:atom, -Tag:atom) is nondet
  127git_tag(Dir, Tag) :-
  128  git(Dir, [tag], Codes),
  129  atom_codes(Atom, Codes),
  130  atomic_list_concat(Tags, '\n', Atom),
  131  (   var(Tag)
  132  ->  member(Tag, Tags),
  133      Tag \== ''
  134  ;   memberchk(Tag, Tags)
  135  ).
 git_version(+Direction:atom, +Version:compound) is semidet
git_version(+Direction:atom, -Version:compound) is nondet
  142git_version(Dir, Version) :-
  143  git_tag(Dir, Tag),
  144  atom_phrase(version(Version), Tag).
 git_version_latest(+Directory:atom, +Version:compound) is semidet
git_version_latest(+Directory:atom, -Version:compound) is semidet
  151git_version_latest(Dir, Version) :-
  152  aggregate_all(set(Version), git_version(Dir, Version), Versions),
  153  predsort(compare_version, Versions, SortedVersions),
  154  last(SortedVersions, Version).
  155
  156
  157
  158
  159
  160% HELPERS %
 git(+Arguments:list(atom)) is semidet
 git(+Dir:atom, +Arguments:list(atom)) is semidet
 git(+Dir:atom, +Arguments:list(atom), -Output:list(code)) is semidet
  166git(Args) :-
  167  git(., Args).
  168
  169
  170git(Dir, Args) :-
  171  git(Dir, Args, _).
  172
  173
  174git(Dir, Args, Output) :-
  175  (   debugging(ppm(git))
  176  ->  atomic_list_concat([git|Args], ' ', Cmd),
  177      debug(ppm(git), "~a", [Cmd])
  178  ;   true
  179  ),
  180  git:git(Args, [directory(Dir),error(Error),output(Output),status(Status)]),
  181  (   Error == []
  182  ->  debug(ppm(git), "~s", [Output])
  183  ;   ansi_format([fg(red)], "~s", [Error])
  184  ),
  185  Status = exit(0)