98_version.pm 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. # $Id: 98_version.pm 15140 2017-09-26 09:20:09Z markusbloch $
  2. package main;
  3. use strict;
  4. use warnings;
  5. sub version_Initialize($$) {
  6. $cmds{version} = { Fn => "CommandVersion",
  7. Hlp=>"[<filter>|revision] [noheader],print SVN version of loaded modules"};
  8. }
  9. #####################################
  10. sub
  11. CommandVersion($$)
  12. {
  13. my ($cl, $param) = @_;
  14. my $noheader = ($param =~ s/(?:^\s*|\s+)noheader\s*$//);
  15. eval { "test" =~ /$param/ };
  16. return "invalid filter regexp" if($@);
  17. my @ret;
  18. my $max = 0;
  19. my $modpath = (exists($attr{global}{modpath}) ? $attr{global}{modpath} : "");
  20. my @files = map {$INC{$_}} keys %INC;
  21. push @files, $0; # path to fhem.pl
  22. push @ret, cfgDB_svnId() if(configDBUsed());
  23. @files = () if($param && $param eq "revision");
  24. foreach my $fn (@files) {
  25. next unless($fn);
  26. next unless($fn =~ /^(?:$modpath.?)?FHEM/ or $fn =~ /fhem.pl$/); # configDB
  27. my $mod_name = ($fn=~ /[\/\\]([^\/\\]+)$/ ? $1 : $fn);
  28. next if($param ne "" && $mod_name !~ /$param/);
  29. next if(grep(/$mod_name/, @ret));
  30. Log 4, "Looking for SVN Id in module $mod_name";
  31. $max = length($mod_name) if($max < length($mod_name));
  32. my $line;
  33. if(!open(FH, $fn)) {
  34. $line = "$fn: $!";
  35. if(configDBUsed()){
  36. Log 4, "Looking for module $mod_name in configDB to find SVN Id";
  37. $line = cfgDB_Fileversion($fn,$line);
  38. }
  39. } else {
  40. while(<FH>) {
  41. chomp;
  42. if(/#.*\$Id\:[^\$\n\r].+\$/) {
  43. $line = $_;
  44. last;
  45. }
  46. }
  47. close(FH);
  48. }
  49. $line = "No Id found for $mod_name" unless($line);
  50. push @ret, $line;
  51. }
  52. my $fhem_revision = version_getRevFromControls();
  53. $fhem_revision = "Latest Revision: $fhem_revision\n\n" if(defined($fhem_revision) && !$noheader);
  54. @ret = map {/\$Id\: (\S+?) (\d+?) (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}Z \S+?) \$/ ? sprintf("%-".$max."s %5d %s",$1,$2,$3) : $_} @ret;
  55. @ret = sort {version_sortModules($a, $b)} grep {($param ne "" ? /$param/ : 1)} @ret;
  56. return "no loaded modules found that match: $param" if($param ne "" && $param ne "revision" && !@ret);
  57. return (((!$param && !$noheader) || $param eq "revision") ? $fhem_revision : "").
  58. ($noheader || !@ret ? "" : sprintf("%-".$max."s %s","File","Rev Last Change\n\n")).
  59. trim(join("\n", grep (($_ =~ /^fhem.pl|\d\d_/), @ret))."\n\n".
  60. join("\n", grep (($_ !~ /^fhem.pl|\d\d_/), @ret))
  61. );
  62. }
  63. #####################################
  64. sub version_sortModules($$)
  65. {
  66. my ($a, $b) = @_;
  67. $a =~ s/^(?:No Id found for |#\s*\$Id\: )//;
  68. $b =~ s/^(?:No Id found for |#\s*\$Id\: )//;
  69. my @a_vals = split(' ', $a);
  70. my @b_vals = split(' ', $b);
  71. # fhem.pl always at top
  72. return -1 if($a_vals[0] eq "fhem.pl");
  73. return 1 if($b_vals[0] eq "fhem.pl");
  74. $a_vals[0] =~ s/^\d\d_//;
  75. $b_vals[0] =~ s/^\d\d_//;
  76. return uc($a_vals[0]) cmp uc($b_vals[0]);
  77. }
  78. sub version_getRevFromControls(;$)
  79. {
  80. my ($name) = @_;
  81. $name //= "fhem";
  82. my $cf = "controls_$name.txt";
  83. my $filename = (-e "./$cf") ? "./$cf" : AttrVal("global","modpath",".")."/FHEM/$cf";
  84. my ($err, @content) = FileRead({FileName => $filename, ForceType => "file"});
  85. if ($err) {
  86. Log 3, "version: unable to open $filename: $err";
  87. return undef;
  88. }
  89. my $revision;
  90. foreach my $l (@content) {
  91. if($l =~ /^REV\s+(\S+.*)$/) {
  92. $revision = $1;
  93. last;
  94. }
  95. }
  96. return $revision;
  97. }
  98. 1;
  99. =pod
  100. =item command
  101. =item summary shows the version of FHEM and all loaded modules.
  102. =item summary_DE zeigt die Version von FHEM und allen geladenen Modulen an
  103. =begin html
  104. <a name="version"></a>
  105. <h3>version</h3>
  106. <ul>
  107. <code>version [&lt;filter&gt;|revision] [noheader]</code>
  108. <br><br>
  109. List the version of fhem.pl and all loaded modules. The optional parameter
  110. can be used to filter the ouput. The special filter value "revision" shows
  111. only the latest revision number since the last update.<br><br>
  112. The optional flag <code>noheader</code> disables the output of the header lines (Latest Revision, File, Rev, Last Change).
  113. <br><br>
  114. When issued via FHEMWEB command line, all executed JavaScript files with their corresponding version will be listed additionally.
  115. <br><br>
  116. Example output of <code>version</code>:
  117. <ul>
  118. <code><br>
  119. Latest Revision: 10814<br><br>
  120. File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rev&nbsp;&nbsp;&nbsp;Last&nbsp;Change<br><br>
  121. fhem.pl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10769&nbsp;2016-02-08&nbsp;12:11:51Z&nbsp;rudolfkoenig<br>
  122. 90_at.pm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10048&nbsp;2015-11-29&nbsp;14:51:40Z&nbsp;rudolfkoenig<br>
  123. 98_autocreate.pm&nbsp;10165&nbsp;2015-12-13&nbsp;11:14:15Z&nbsp;rudolfkoenig<br>
  124. 00_CUL.pm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10146&nbsp;2015-12-10&nbsp;10:17:42Z&nbsp;rudolfkoenig<br>
  125. 10_CUL_HM.pm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10411&nbsp;2016-01-08&nbsp;15:18:17Z&nbsp;martinp876<br>
  126. ...
  127. </code>
  128. </ul>
  129. <br>
  130. Example output of <code>version fhem.pl</code>:
  131. <ul>
  132. <code><br>
  133. File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rev&nbsp;&nbsp;&nbsp;Last&nbsp;Change<br><br>
  134. fhem.pl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10397&nbsp;2016-01-07&nbsp;08:36:49Z&nbsp;rudolfkoenig<br>
  135. </code>
  136. </ul>
  137. <br>
  138. Example output of <code>version fhem.pl noheader</code>:
  139. <ul>
  140. <code><br>
  141. fhem.pl&nbsp;10397&nbsp;2016-01-07&nbsp;08:36:49Z&nbsp;rudolfkoenig<br>
  142. </code>
  143. </ul>
  144. </ul>
  145. =end html
  146. =begin html_DE
  147. <a name="version"></a>
  148. <h3>version</h3>
  149. <ul>
  150. <code>version [&lt;filter&gt;|revision] [noheader]</code>
  151. <br><br>
  152. Gibt die Versionsinformation von fhem.pl und aller geladenen Module aus. Mit
  153. dem optionalen Parameter kann man die Ausgabe filtern. Der spezielle Filterwert "revision"
  154. zeigt nur die aktuellste Revisions-Nummer seit dem letzten Update an.
  155. <br><br>
  156. Der optionale Parameter <code>noheader</code> unterdr&uuml;ckt die Ausgabe des Listenkopfs (Latest Revision, File, Rev, Last Change).
  157. <br><br>
  158. Wenn dieser Befehl &uuml;ber die FHEMWEB-Kommandozeile eingegeben wird, werden zus&auml;tzlich alle aktuell geladenen JavaScript-Dateien mit ihren zugeh&ouml;rigen Versionsinformationen angezeigt.
  159. <br><br>
  160. Beispiel der Ausgabe von <code>version</code>:
  161. <ul>
  162. <code><br>
  163. Latest Revision: 10814<br><br>
  164. File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rev&nbsp;&nbsp;&nbsp;Last&nbsp;Change<br><br>
  165. fhem.pl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10769&nbsp;2016-02-08&nbsp;12:11:51Z&nbsp;rudolfkoenig<br>
  166. 90_at.pm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10048&nbsp;2015-11-29&nbsp;14:51:40Z&nbsp;rudolfkoenig<br>
  167. 98_autocreate.pm&nbsp;10165&nbsp;2015-12-13&nbsp;11:14:15Z&nbsp;rudolfkoenig<br>
  168. 00_CUL.pm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10146&nbsp;2015-12-10&nbsp;10:17:42Z&nbsp;rudolfkoenig<br>
  169. 10_CUL_HM.pm&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10411&nbsp;2016-01-08&nbsp;15:18:17Z&nbsp;martinp876<br>
  170. ...
  171. </code>
  172. </ul>
  173. <br>
  174. Beispiel der Ausgabe von <code>version fhem</code>:
  175. <ul>
  176. <code><br>
  177. File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rev&nbsp;&nbsp;&nbsp;Last&nbsp;Change<br><br>
  178. fhem.pl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10769&nbsp;2016-02-08&nbsp;12:11:51Z&nbsp;rudolfkoenig<br>
  179. </code>
  180. </ul>
  181. <br>
  182. Beispiel der Ausgabe von <code>version fhem.pl noheader</code>:
  183. <ul>
  184. <code><br>
  185. fhem.pl&nbsp;10769&nbsp;2016-02-08&nbsp;12:11:51Z&nbsp;rudolfkoenig<br>
  186. </code>
  187. </ul>
  188. </ul>
  189. =end html_DE
  190. =cut