Debugging Prolog

335 views
Skip to first unread message

Kenny Ho

unread,
Sep 19, 2014, 2:12:41 PM9/19/14
to repo-d...@googlegroups.com
Hi,

I am new to Prolog and I am trying to create some custom rules.  (I am essentially trying to implement some kind of file whitelist on submit.)  What is the best way to debug Prolog with Gerrit?  I know there is the Prolog shell but it doesn't have gerrit facts.  I also know that I can do the "test-submit rule " on the server but when something failed I am not quite sure where to go.  (Sometimes it prints error_log, which I can check, but sometimes I just get "Processing of prolog script failed" because my script is wrong.)  I know this is a very "imperative" things to ask, but is there a way I can 'print' something from within rules.pl?  (let's say if I want to find out what I am getting back from commit_delta/3 w.r.t. the new path part, how can I do that?)

Kenny Ho

unread,
Sep 19, 2014, 4:35:15 PM9/19/14
to repo-d...@googlegroups.com
So I ended up using the label field as a debug output.  For example:

submit_rule(S) :-
  gerrit
:commit_delta('.*', T, P, _),
  S
=.. [submit | [label(P, need(_))] ].

As for the whitelisting part, I got to a point where I can create an atom with the name of the non-whitelisted file, but when I try to make a need-label from it I get an error.
whitelisted(Ls, F, Out) :-
  regex_matches('^t.*', F),!;
  regex_matches('^m.*', F),!;
  atom_concat('Need-whitelist-', F, Wl),
  Out = Wl.

submit_rule(S) :-
  gerrit:default_submit(X),
  X =.. [submit | Ls],
  gerrit:commit_delta('.*', T, P, _), 
  whitelisted(Ls, P, Wlabels),
  S =.. [submit | [label(Wlabels, need(_))] ].

For example, if I have three files in the commit and one of them is "bob.txt", the above code will give me three labels: one with "Need-whitelist-bob.txt" and two others two label with empty string.  How can I eliminate the 2 empty labels and combine them into one submit (with the labels returned from default_submit?  Can anyone help?

Kenny Ho

unread,
Sep 19, 2014, 6:25:24 PM9/19/14
to repo-d...@googlegroups.com
Actually... let me clarify the question a bit.  When commit_delta/3 (http://gerrit-review.googlesource.com/Documentation/prolog-change-facts.html) return on a patch that has multiple changes, is returning a list or something else?  From what I can observe so far, seems like it's something else as the whitelisted predicate is being run multiple times (once for each path that matches the commit_delta regex.)  How would I "reduce" these multiple 'runs' back into one action?  (Namely, to add the "need-whitelist" label or not.)

Saša Živkov

unread,
Sep 22, 2014, 7:57:07 AM9/22/14
to Kenny Ho, repo-d...@googlegroups.com
On Fri, Sep 19, 2014 at 10:35 PM, Kenny Ho <y2k...@gmail.com> wrote:
So I ended up using the label field as a debug output.
 
This is a good idea and the one I wanted to propose. 
If I remember well, before the "test-submit rule" command was refactored to use the REST code
it was possible to return anything from the submit_rule and display it raw at the client side.
Looks like this feature is lost and we must take care to always return a proper submit term in order
to get something useful back to the client.


For example:

submit_rule(S) :-
  gerrit
:commit_delta('.*', T, P, _),
  S
=.. [submit | [label(P, need(_))] ].

As for the whitelisting part, I got to a point where I can create an atom with the name of the non-whitelisted file, but when I try to make a need-label from it I get an error.
whitelisted(Ls, F, Out) :-
The "Ls" is not used... you can remove it.
 
  regex_matches('^t.*', F),!;
  regex_matches('^m.*', F),!;
Looks like here is your problem (the OR operator ';')
Even if neither if the two above matches the evaluation will continue as you have the OR operator
and the atom_concat will succeed etc...

Try instead:

whitelisted(Ls, F, Out) :-
    (regex_matches('^t.*', F); regex_matches('^m.*', F)) ,
  atom_concat('Need-whitelist-', F, Wl),
  Out = Wl.
 

  atom_concat('Need-whitelist-', F, Wl),
  Out = Wl.

submit_rule(S) :-
  gerrit:default_submit(X),
  X =.. [submit | Ls],
  gerrit:commit_delta('.*', T, P, _), 
  whitelisted(Ls, P, Wlabels),
  S =.. [submit | [label(Wlabels, need(_))] ].

For example, if I have three files in the commit and one of them is "bob.txt", the above code will give me three labels: one with "Need-whitelist-bob.txt" and two others two label with empty string.  How can I eliminate the 2 empty labels and combine them into one submit (with the labels returned from default_submit?  Can anyone help?



On Friday, September 19, 2014 2:12:41 PM UTC-4, Kenny Ho wrote:
Hi,

I am new to Prolog and I am trying to create some custom rules.  (I am essentially trying to implement some kind of file whitelist on submit.)  What is the best way to debug Prolog with Gerrit?  I know there is the Prolog shell but it doesn't have gerrit facts.  I also know that I can do the "test-submit rule " on the server but when something failed I am not quite sure where to go.  (Sometimes it prints error_log, which I can check, but sometimes I just get "Processing of prolog script failed" because my script is wrong.)  I know this is a very "imperative" things to ask, but is there a way I can 'print' something from within rules.pl?  (let's say if I want to find out what I am getting back from commit_delta/3 w.r.t. the new path part, how can I do that?)

--
--
To unsubscribe, email repo-discuss...@googlegroups.com
More info at http://groups.google.com/group/repo-discuss?hl=en

---
You received this message because you are subscribed to the Google Groups "Repo and Gerrit Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to repo-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kenny Ho

unread,
Oct 8, 2014, 10:46:10 AM10/8/14
to repo-d...@googlegroups.com, y2k...@gmail.com
I ended up making the whitelist work with this (but since I am completely new to Prolog, I am not sure if it's the best/efficient way to go about it:
whitelisted(B, P) :-
  regex_matches('refs/meta/config', B), regex_matches('rules.pl', P);
  regex_matches('^t.*', P);
  %  regex_matches('^b.*', P);
  regex_matches('^m.*', P).

add_need_whitelist(In, Out) :-
  gerrit:commit_delta('.*', T, P, _),
  gerrit:change_branch(B),
  \+ whitelisted(B, P), %if not in the whitelist, stop it
  Out = [ label('Need-whitelisting', impossible(_)) | In ], !. %cut once it's true
add_need_whitelist(In, Out) :-
  gerrit:change_owner(A),
  Out = [ label('Need-whitelisting', ok(A)) | In ].

submit_rule(S) :-
  gerrit:default_submit(X),
  X =.. [submit | Ls],
  add_need_whitelist(Ls, R),
  S =.. [submit | R ].

I also tries to make things a bit more modular but taking the whitelisted(B, P) :- part to another file.  But when I try to use consult or include inside rules.pl, I get error.  Is that something not supported with Prolog on Gerrit?

The error:
Caused by: com.googlecode.prolog_cafe.lang.TermException: permission_error(assertz(:(user,:-(consult(w
hitelist),true))),modify,static_procedure,:(user,/(consult,1)),_2C3C1A6F)

Kenny

Saša Živkov

unread,
Oct 8, 2014, 11:10:07 AM10/8/14
to Kenny Ho, repo-d...@googlegroups.com
On Wed, Oct 8, 2014 at 4:46 PM, Kenny Ho <y2k...@gmail.com> wrote:
I ended up making the whitelist work with this (but since I am completely new to Prolog, I am not sure if it's the best/efficient way to go about it:
whitelisted(B, P) :-
  regex_matches('refs/meta/config', B), regex_matches('rules.pl', P);
  regex_matches('^t.*', P);
  %  regex_matches('^b.*', P);
  regex_matches('^m.*', P).

add_need_whitelist(In, Out) :-
  gerrit:commit_delta('.*', T, P, _),
  gerrit:change_branch(B),
  \+ whitelisted(B, P), %if not in the whitelist, stop it
  Out = [ label('Need-whitelisting', impossible(_)) | In ], !. %cut once it's true
add_need_whitelist(In, Out) :-
  gerrit:change_owner(A),
  Out = [ label('Need-whitelisting', ok(A)) | In ].

submit_rule(S) :-
  gerrit:default_submit(X),
  X =.. [submit | Ls],
  add_need_whitelist(Ls, R),
  S =.. [submit | R ].

I also tries to make things a bit more modular but taking the whitelisted(B, P) :- part to another file.  But when I try to use consult or include inside rules.pl, I get error.  Is that something not supported with Prolog on Gerrit?
 
I don't think that we support include and/or consult.
Reply all
Reply to author
Forward
0 new messages