dev-server 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #!/usr/bin/perl
  2. use local::lib;
  3. use v5.10;
  4. use strict;
  5. use warnings;
  6. use List::Util qw( any );
  7. use Mojo::Server::Morbo ();
  8. use Time::HiRes qw( sleep );
  9. $| = 1;
  10. my @switches = grep {/^-/} @ARGV;
  11. $ENV{DEBUG} = 1;
  12. $ENV{LOGBOT_CONFIG} = join(',', grep { !/^-/ } @ARGV) || '_development';
  13. $ENV{LOGBOT_STATUS_PASSWORD} = '';
  14. # asset watch
  15. {
  16. my $pid = fork();
  17. if (defined($pid) && $pid == 0) {
  18. my $make = Make->new();
  19. while (1) {
  20. $make->execute() if $make->updated();
  21. sleep(0.25);
  22. }
  23. }
  24. }
  25. # memcached
  26. if (!any { $_ eq '--no-cache' } @switches) {
  27. my $pid = fork();
  28. if (defined($pid) && $pid == 0) {
  29. my $verbose = any { $_ eq '-v' || $_ eq '--verbose' } @switches;
  30. ## no critic (InputOutput::RequireBriefOpen)
  31. open(my $mc, '-|', 'memcached -vv 2>&1') || die "failed to start memcached: $!\n";
  32. say 'memcached listening on :11211' unless $verbose;
  33. while (<$mc>) {
  34. next unless $verbose;
  35. next
  36. if /^slab class/
  37. || /^<\d+ new auto-negotiating/
  38. || /^<\d+ connection closed/
  39. || /^\d+: Client using/;
  40. print 'memcached: ', $_;
  41. }
  42. close($mc) || die $!;
  43. ## use critic
  44. exit;
  45. }
  46. }
  47. # web server
  48. my $morbo = Mojo::Server::Morbo->new();
  49. $morbo->backend->watch(['web/templates/', 'web/templates/layouts/', 'lib/LogBot', 'lib/Logbot/Web']);
  50. $morbo->run('logbot-web');
  51. package Make;
  52. use strict;
  53. use v5.10;
  54. use warnings;
  55. use FindBin qw( $RealBin );
  56. use lib "$RealBin/lib";
  57. use LogBot::Util qw( file_time run );
  58. sub new {
  59. my ($class) = @_;
  60. return bless({ make => "$RealBin/dev-make", ts => 0, first => 1 }, $class);
  61. }
  62. sub execute {
  63. my ($self) = @_;
  64. run($self->{make}, delete $self->{first} ? '-q' : '', delete $self->{all} ? '-B' : '');
  65. }
  66. sub updated {
  67. my ($self) = @_;
  68. if (file_time($self->{make}) != $self->{ts}) {
  69. $self->{all} = $self->{ts} != 0;
  70. $self->{ts} = file_time($self->{make});
  71. $self->{files} = $self->_prerequisites();
  72. $self->{files_ts} = {};
  73. }
  74. my $updated = 0;
  75. foreach my $file (@{ $self->{files} }) {
  76. if (!-e $file) {
  77. $self->{ts} = 0;
  78. $updated = 1;
  79. } else {
  80. my $ts = file_time($file);
  81. if ($ts != ($self->{files_ts}->{$file} // 0)) {
  82. $updated = 1;
  83. }
  84. $self->{files_ts}->{$file} = $ts;
  85. }
  86. }
  87. return $updated;
  88. }
  89. sub _prerequisites {
  90. my ($self) = @_;
  91. open(my $dm, '-|', $self->{make}, 'deps') or die $!;
  92. chomp(my @files = <$dm>);
  93. close($dm) or die $!;
  94. return \@files;
  95. }
  96. 1;