Branch: Tag:

2010-09-05

2010-09-05 14:09:37 by Marcus Comstedt <marcus@mc.pp.se>

Initial framework.

1: + #! /usr/bin/env pike    -  + constant hooks = ([ +  "post-checkout" : PostCheckoutHook, + ]); +  + constant filters = ([ +  "nice_ident" : NiceIdentFilter, + ]); +  +  +  + constant filterops = ({ "clean", "smudge" }); +  + void fail(string msg, mixed ... args) + { +  werror(msg, @args); +  exit(1); + } +  + void iofailn(int errno, string msg, mixed ... args) + { +  fail(msg+": %s\n", @args, strerror(errno)); + } +  + void iofail(string msg, mixed ... args) + { +  iofailn(errno(), msg, @args); + } +  + string run_git_ex(int max_exitcode, string ... args) + { +  mapping res = Process.run(({"git"})+args); +  if (res->exitcode > max_exitcode) { +  werror(res->stderr); +  fail("git exited with code %d\n", res->exitcode); +  } +  return res->stdout; + } +  + string run_git(string ... args) + { +  return run_git_ex(0, @args); + } +  + /* Hooks */ +  + class PostCheckoutHook + { +  int hook(string ... args) +  { +  write("post-checkout %O\n", args); +  } + } +  + /* Filters */ +  + class NiceIdentFilter + { +  int clean(string ... args) +  { +  werror("clean %O\n", args); +  Process.system("cat"); +  } +  +  int smudge(string ... args) +  { +  werror("smudge %O\n", args); +  Process.system("cat"); +  } + } +  + /* Main helper */ +  + class GitHelper + { +  void setup_hooks() +  { +  constant hooksdir = "hooks"; +  if (!sizeof(hooks)) +  return; +  if (!file_stat(hooksdir)) { +  write("Creating the hooks directory\n"); +  if(!mkdir(hooksdir)) +  iofail("Failed to create %s", hooksdir); +  } +  foreach (hooks; string name; ) { +  string path = combine_path(hooksdir, name); +  Stdio.Stat s = file_stat(path, 1); +  if (!s) { +  write("Installing %s\n", path); +  System.symlink(__FILE__, path); +  } else if(s->islnk) { +  /* Already setup ok, it seems */ +  } else { +  write("Hook %s already exists, so won't overwrite it...", name); +  } +  } +  } +  +  void setup_filter(string name, string op) +  { +  string confname = "filter."+name+"."+op; +  string old = String.trim_all_whites(run_git_ex(1, "config", "--get", confname)); +  string cmd = __FILE__+" filter_"+name+"_"+op; +  if(old == "") { +  write("Installing filter operation %s\n", confname); +  run_git("config", confname, cmd); +  } else if(old == cmd) { +  /* Already has correct value */ +  } else { +  write("Filter operation %s is already set to %s, not modifying\n", +  confname, old); +  } +  } +  +  void setup_filters() +  { +  foreach (filters; string name; program fprog) { +  object filter = fprog(); +  foreach (filterops; ; string op) +  if(filter[op]) +  setup_filter(name, op); +  } +  } +  +  int setup(array(string) args) +  { +  if (sizeof(args)) { +  werror("githelper.pike should be invoked without arguments...\n"); +  return 1; +  } +  if (!cd(String.trim_all_whites(run_git("rev-parse", "--git-dir")))) +  iofail("Failed to cd to .git directory"); +  setup_hooks(); +  setup_filters(); +  return 0; +  } + } +  + string get_filter_op(string arg) + { +  if (!has_prefix(arg, "filter_")) +  return 0; +  foreach (filterops; ; string op) +  if (has_suffix(arg, "_"+op)) +  return op; + } +  + int main(int argc, array(string) argv) + { +  string command_name = basename(argv[0]); +  if (hooks[command_name]) +  return hooks[command_name]()->hook(@argv[1..]); +  else if (command_name == "githelper.pike") { +  string fop; +  if (argc>1 && (fop = get_filter_op(argv[1]))) { +  string filter = argv[1][7..sizeof(argv[1])-(sizeof(fop)+2)]; +  if (filters[filter]) { +  object f = filters[filter](); +  if (!f[fop]) { +  +  } else +  return f[fop](@argv[2..]); +  } else { +  werror("Unknown filter %s!\n", filter); +  return 1; +  } +  } else +  return GitHelper()->setup(argv[1..]); +  } else { +  werror("Unknown invocation method %s!\n", command_name); +  return 1; +  } + }   Newline at end of file added.