summaryrefslogtreecommitdiff
path: root/IkiWiki/Rcs/mercurial.pm
blob: 8c3f03e07145a84f38e80f515b0918be26c9e382 (plain)
  1. #!/usr/bin/perl
  2. package IkiWiki;
  3. use warnings;
  4. use strict;
  5. use IkiWiki;
  6. use Encode;
  7. use open qw{:utf8 :std};
  8. sub mercurial_log($) {
  9. my $out = shift;
  10. my @infos;
  11. while (<$out>) {
  12. my $line = $_;
  13. my ($key, $value);
  14. if (/^description:/) {
  15. $key = "description";
  16. $value = "";
  17. # slurp everything as the description text
  18. # until the next changeset
  19. while (<$out>) {
  20. if (/^changeset: /) {
  21. $line = $_;
  22. last;
  23. }
  24. $value .= $_;
  25. }
  26. local $/ = "";
  27. chomp $value;
  28. $infos[$#infos]{$key} = $value;
  29. }
  30. chomp $line;
  31. ($key, $value) = split /: +/, $line, 2;
  32. if ($key eq "changeset") {
  33. push @infos, {};
  34. # remove the revision index, which is strictly
  35. # local to the repository
  36. $value =~ s/^\d+://;
  37. }
  38. $infos[$#infos]{$key} = $value;
  39. }
  40. close $out;
  41. return @infos;
  42. }
  43. sub rcs_update () { #{{{
  44. my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "update");
  45. if (system(@cmdline) != 0) {
  46. warn "'@cmdline' failed: $!";
  47. }
  48. } #}}}
  49. sub rcs_prepedit ($) { #{{{
  50. return "";
  51. } #}}}
  52. sub rcs_commit ($$$;$$) { #{{{
  53. my ($file, $message, $rcstoken, $user, $ipaddr) = @_;
  54. if (defined $user) {
  55. $user = possibly_foolish_untaint($user);
  56. }
  57. elsif (defined $ipaddr) {
  58. $user = "Anonymous from ".possibly_foolish_untaint($ipaddr);
  59. }
  60. else {
  61. $user = "Anonymous";
  62. }
  63. $message = possibly_foolish_untaint($message);
  64. if (! length $message) {
  65. $message = "no message given";
  66. }
  67. my @cmdline = ("hg", "-q", "-R", $config{srcdir}, "commit",
  68. "-m", $message, "-u", $user);
  69. if (system(@cmdline) != 0) {
  70. warn "'@cmdline' failed: $!";
  71. }
  72. return undef; # success
  73. } #}}}
  74. sub rcs_commit_staged ($$$) {
  75. # Commits all staged changes. Changes can be staged using rcs_add,
  76. # rcs_remove, and rcs_rename.
  77. my ($message, $user, $ipaddr)=@_;
  78. error("rcs_commit_staged not implemented for mercurial"); # TODO
  79. }
  80. sub rcs_add ($) { # {{{
  81. my ($file) = @_;
  82. my @cmdline = ("hg", "-q", "-R", "$config{srcdir}", "add", "$config{srcdir}/$file");
  83. if (system(@cmdline) != 0) {
  84. warn "'@cmdline' failed: $!";
  85. }
  86. } #}}}
  87. sub rcs_remove ($) { # {{{
  88. my ($file) = @_;
  89. error("rcs_remove not implemented for mercurial"); # TODO
  90. } #}}}
  91. sub rcs_rename ($$) { # {{{
  92. my ($src, $dest) = @_;
  93. error("rcs_rename not implemented for mercurial"); # TODO
  94. } #}}}
  95. sub rcs_recentchanges ($) { #{{{
  96. my ($num) = @_;
  97. my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", $num,
  98. "--style", "default");
  99. open (my $out, "@cmdline |");
  100. eval q{use Date::Parse};
  101. error($@) if $@;
  102. my @ret;
  103. foreach my $info (mercurial_log($out)) {
  104. my @pages = ();
  105. my @message = ();
  106. foreach my $msgline (split(/\n/, $info->{description})) {
  107. push @message, { line => $msgline };
  108. }
  109. foreach my $file (split / /,$info->{files}) {
  110. my $diffurl = $config{'diffurl'};
  111. $diffurl =~ s/\[\[file\]\]/$file/go;
  112. $diffurl =~ s/\[\[r2\]\]/$info->{changeset}/go;
  113. push @pages, {
  114. page => pagename($file),
  115. diffurl => $diffurl,
  116. };
  117. }
  118. my $user = $info->{"user"};
  119. $user =~ s/\s*<.*>\s*$//;
  120. $user =~ s/^\s*//;
  121. push @ret, {
  122. rev => $info->{"changeset"},
  123. user => $user,
  124. committype => "mercurial",
  125. when => str2time($info->{"date"}),
  126. message => [@message],
  127. pages => [@pages],
  128. };
  129. }
  130. return @ret;
  131. } #}}}
  132. sub rcs_diff ($) { #{{{
  133. # TODO
  134. } #}}}
  135. sub rcs_getctime ($) { #{{{
  136. my ($file) = @_;
  137. # XXX filename passes through the shell here, should try to avoid
  138. # that just in case
  139. my @cmdline = ("hg", "-R", $config{srcdir}, "log", "-v", "-l", '1',
  140. "--style", "default", "$config{srcdir}/$file");
  141. open (my $out, "@cmdline |");
  142. my @log = mercurial_log($out);
  143. if (length @log < 1) {
  144. return 0;
  145. }
  146. eval q{use Date::Parse};
  147. error($@) if $@;
  148. my $ctime = str2time($log[0]->{"date"});
  149. return $ctime;
  150. } #}}}
  151. 1