githelper.git / githelper.pike

version» Context lines:

githelper.git/githelper.pike:352:    GitAttributes attrs;       private string git_dir;       string get_git_dir()    {    return git_dir ||    (git_dir = String.trim_all_whites(run_git("rev-parse", "--git-dir")));    }    +  class Plugin +  { +  optional string check_message_body(string sha, array(string) headers, +  string body); +  +  optional int(0..1) check_commit(string branch, string sha, +  array(string) paths); +  } +  +  Plugin plugin; +  + #ifdef COMMIT_PLUGIN +  private class PluginHandler +  { +  mixed resolv(string symbol, string file) +  { +  switch(symbol) { +  case "get_git_dir": return get_git_dir; +  } +  return master()->resolv(symbol, file); +  } +  } +  +  private PluginHandler plugin_handler = PluginHandler(); +  +  protected void create() +  { +  string plugin_path = combine_path(get_git_dir(), +  "hooks/githelper-plugins", +  COMMIT_PLUGIN); +  if (Stdio.exist(plugin_path)) { +  program(Plugin) plugin_program = +  compile_file(plugin_path, plugin_handler); +  plugin = plugin_program(); +  } else { +  write("NOTICE: Plugin %s not found.\n", plugin_path); +  write("You may want to reinstall githelper.\n"); +  } +  } + #endif +     string get_file(string filename, int|void allow_empty);    string get_old_file(string filename, int|void allow_empty);    int entry_is_new(string filename) { return 0; }       int find_expanded_ident(string data)    {    int p=0;    while ((p = search(data, DOLLAR"Id", p))>=0) {    if (data[p..p+3] != unexpanded_id) {    int p2 = search(data, DOLLAR, p+3), p3 = search(data, "\n", p+3);
githelper.git/githelper.pike:471:    }   }      class CommitHookUtilsRepo   {    inherit CommitHookUtils;       protected string sha;    protected string parent;    +  protected mapping(string:array(string)) commit_paths = ([]); +     string get_file(string filename, int|void allow_empty)    {    return get_committed_file(sha, filename, allow_empty);    }       string get_old_file(string filename, int|void allow_empty)    {    return get_committed_file(parent, filename, allow_empty);    }   
githelper.git/githelper.pike:492:    {    return (!sizeof(run_git("ls-tree", parent, "--", filename))) &&    sizeof(run_git("ls-tree", sha, "--", filename));    }       string check_commit_msg(string commit)    {    string message = run_git("cat-file", "commit", commit);    string encoding = 0;    string headers = (message/"\n\n")[0]; +  string body = (message/"\n\n")[1..]*"\n\n";    foreach(headers/"\n", string headerline) {    if(has_prefix(headerline, "encoding "))    encoding = headerline[9..];    }    -  return check_encoding(message, encoding); +  string msg = check_encoding(message, encoding); +  +  if (msg) return msg; +  +  if (plugin && plugin->check_message_body) { +  return plugin->check_message_body(commit, headers/"\n", body);    }    -  +  return 0; +  } +     int check_commit(string sha)    {    if (!has_prefix(sha, "HEAD"))    write("Checking commit %s\n", sha);    this_program::sha = sha;    array(string) parents = split_lf(run_git("rev-list", "--parents",    "-n", "1", sha))[0] / " ";    if (sizeof(parents) > 1)    parent = parents[1]; // First parent, sha^    else    parent = String.trim_all_whites(run_git("hash-object", "-t", "tree", "/dev/null")); // Empty tree -  files_to_commit = +  commit_paths[sha] = files_to_commit =    split_z(run_git("diff", "--name-only", "-z", sha, parent));    attrs = GitAttributes(get_file(".gitattributes", 1));    string ts_test = check_commit_timestamps(sha);    int err = 0;    if (ts_test) {    write("Invalid timestamps: %s\n", ts_test);    err = 1;    }    string cm_test = check_commit_msg(sha);    if (cm_test) {
githelper.git/githelper.pike:618:    ACCESS_EXISTING = 3, // May be updated to any previously existing commit.    ACCESS_FULL = 4, // rebase/delete branch, move/delete tag, etc.    };       protected mapping(string:AccessLevel) groups = ([    "scratch": ACCESS_FULL,    ]);       protected array(string) commits_to_check = ({});    +  protected mapping(string:array(string)) branch_commits = ([]); +     protected void parse_groups(string user)    {    string git_dir = get_git_dir();       groups[user] = ACCESS_FULL;    groups["tracking"] = ACCESS_EXISTING;       string group_data = Stdio.read_bytes(combine_path(git_dir, "info/group"));       if (!group_data) return;
githelper.git/githelper.pike:751:    "-n", "2", old_sha));    array(string) fp_path = split_lf(run_git("rev-list", "--first-parent",    (sizeof(old_depth)<2?    new_sha :    old_sha+"^.."+new_sha)));    if (search(fp_path, old_sha)<0) {    write("Commit %s does not contain %s in its first-parent ancestry.\nDid you pull with merge instead of rebase?\n", new_sha, old_sha);    return 1;    }    -  commits_to_check += split_lf(run_git("rev-list", old_sha+".."+new_sha)); +  array(string) commits = +  reverse(split_lf(run_git("rev-list", old_sha+".."+new_sha))); +  +  branch_commits[ref_name] += commits; +  commits_to_check += commits;    return 0;    }    }       int check_push(string git_user,    string old_sha, string new_sha, string ref_name)    {    AccessLevel access_level;    if(!(access_level = check_access(ref_name, git_user))) return 1;    if (has_prefix(ref_name, "refs/tags/")) {
githelper.git/githelper.pike:785:    foreach(split_lf(Stdio.stdin->read()), string line) {    array(string) args = line / " ";    if(sizeof(args) != 3)    fail("Unexpected input line to pre-receive hook: %s\n", line);    if(check_push(git_user, @args))    return 1;    }    foreach(Array.uniq(commits_to_check), string sha)    if(check_commit(sha))    return 1; +  +  if (plugin && plugin->check_commit) { +  foreach(sort(indices(branch_commits)), string branch) { +  foreach(branch_commits[branch], string sha) { +  if (plugin->check_commit(branch, sha, commit_paths[sha])) { +  return 1; +  } +  } +  } +  } +     return 0;    }   }      /* Do housekeeping after a commit */      class PostCommitHook   {    inherit CommitHookUtilsRepo;