123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197(* Yoann Padioleau
*
* Copyright (C) 2009, 2013 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation, with the
* special exception on linking described in file license.txt.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
* license.txt for more details.
*)openCommonopenLib_vcs(*****************************************************************************)(* Prelude *)(*****************************************************************************)(*
* less: could use a converter like maybe a git-hg if it exists?
*
* history:
* - done for aComment to study the history of repo in under mercurial.
* - extended for cmf --deadcode
*)(*****************************************************************************)(* Wrappers *)(*****************************************************************************)letpr2,_pr2_once=Common2.mk_pr2_wrappersFlag_version_control.verbose(*****************************************************************************)(* Helpers *)(*****************************************************************************)(* less: factorize with Git.exec_cmd *)letexec_cmd~basedirs=letcmd=Lib_vcs.goto_dirbasedir^sinpr2(spf"executing: %s"s);letret=Sys.commandcmdinif(ret<>0)thenfailwith("pb with command: "^s)(*****************************************************************************)(* Commands *)(*****************************************************************************)(* ex:
stevel 7785c3469156 Thu Aug 30 00:13:38 2007 -0400: /*
*)letannotate_regexp="^"^"[ \t]*\\([^ \t]+\\)[ \t]+"^"\\([A-Za-z0-9]+\\)[ \t]+"^"[A-Za-z]+"^"[ \t]+"^"\\([A-Za-z]+\\)"^"[ \t]+"^(* month *)"\\([0-9]+\\)"^"[ \t]"^(* day *)"[0-9]+"^":"^"[0-9]+"^":"^"[0-9]+"^"[ \t]"^"\\([0-9]+\\)"^"[ \t]"^"-"^(* year *)".*"(* rest of line *)letannotate2?(basedir="")filename=(*
can add -f to follow rename and copy, in that case maybe add to add
it to hg log too
can add -u for user
*)letcmd=(goto_dirbasedir^"hg annotate -u -f -c -d "^filename^" 2>&1")in(* pr2 cmd; *)letxs=Common.cmd_to_listcmdin(*let ys = Common.cat (Common.filename_of_db (basedir,filename)) in*)letannots=xs|>Common.map_filter(funs->ifs=~annotate_regexpthenlet(author,commitid,month_str,day,year)=Common.matched5sinSome(VersionIdcommitid,Authorauthor,Common2.mk_date_dmy(s_to_iday)(Common2.int_of_month(Common2.month_of_stringmonth_str))(s_to_iyear))elsebeginpr2("hg annotate wrong line: "^s);Noneend)in(* files lines are 1_based, so add this dummy 0 entry *)Array.of_list(dummy_annotation::annots)letannotate?basedira=Common.profile_code"Hg.annotate"(fun()->annotate2?basedira)(* ------------------------------------------------------------------------ *)letannotate_raw?(basedir="")filename=letcmd=(goto_dirbasedir^"hg annotate -u -f -c -d "^filename^" 2>&1")inletxs=Common.cmd_to_listcmdinletannots=xs|>Common.map_filter(funs->ifs=~annotate_regexpthenSomeselsebegin(* pr2 ("hg annotate wrong line: " ^ s); *)Noneend)inArray.of_list(""::annots)(* ------------------------------------------------------------------------ *)(* ex:
date: Thu Aug 30 00:13:38 2007 -0400
*)letdate_regexp="date:[ \t]+"^"[A-Za-z]+"^"[ \t]+"^"\\([A-Za-z]+\\)"^"[ \t]+"^(* month *)"\\([0-9]+\\)"^"[ \t]"^(* day *)"[0-9]+"^":"^"[0-9]+"^":"^"[0-9]+"^"[ \t]"^"\\([0-9]+\\)"^"[ \t]"^"-"^(* year *)".*"(* rest of line *)letdate_file_creation2?(basedir="")file=letcmd=(goto_dirbasedir^"hg log -f "^file^" 2>&1")inletxs=Common.cmd_to_listcmdinletxs=List.revxsin(* could also hg log ... | tac *)xs|>Common.find_some(funs->ifs=~date_regexpthenlet(month_str,day,year)=Common.matched3sinSome(Common2.mk_date_dmy(s_to_iday)(Common2.int_of_month(Common2.month_of_stringmonth_str))(s_to_iyear))elseNone)letdate_file_creation?basedira=Common.profile_code"Hg.date_file"(fun()->date_file_creation2?basedira)(*****************************************************************************)(* Repository operations *)(*****************************************************************************)letgrep~basedirstr=letcmd=(goto_dirbasedir^(spf"hg locate -0 | xargs -0 grep --files-with-matches %s"str))inlet(xs,status)=Common2.cmd_to_list_and_statuscmdin(* According to grep man page, non-zero exit code is expected when
* there are no matches.
* According to xargs man page, it returns 123 if one of his subcommand
* returns something between 1 and 125
*)matchxs,statuswith|[],Unix.WEXITEDnwhenn>0->[]|xs,Unix.WEXITED0|xs,Unix.WEXITED123->xs|_->raise(CmdError(status,(spf"CMD = %s, RESULT = %s"cmd(Common.dump(status,xs)))))letshow~basedirfilecommitid=lettmpfile=Common.new_temp_file"hg_cat"".cat"inletstr_commit=Lib_vcs.s_of_versionidcommitidinletcmd=(spf"hg cat -r '%s' %s > %s"str_commitfiletmpfile)inexec_cmd~basedircmd;tmpfileletfiles_involved_in_diff~basedircommitid=letstr_commit=Lib_vcs.s_of_versionidcommitidinletcmd=goto_dirbasedir^spf"hg status --change '%s'"str_commitinletxs=Common.cmd_to_listcmdinxs|>List.mapLib_vcs.parse_file_status