source: perl/lib/BarnOwl/ModuleLoader.pm @ 167044b

debianrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 167044b was 167044b, checked in by Nelson Elhage <nelhage@mit.edu>, 13 years ago
Support string hook entries. perlwrap.pm: Support calling and adding string hook entries in BarnOwl::Hook IRC.pm: Switch our hooks to use string entries Jabber.pm: Switch our hooks to use string entries ModuleLoader.pm: No longer clear all hooks on reload This should have the net effect that we can safely reload single modules.
  • Property mode set to 100644
File size: 3.3 KB
Line 
1use strict;
2use warnings;
3
4package BarnOwl::ModuleLoader;
5
6use lib (BarnOwl::get_data_dir() . "/modules/");
7use PAR (BarnOwl::get_data_dir() . "/modules/*.par");
8use PAR (BarnOwl::get_config_dir() . "/modules/*.par");
9
10our %modules;
11
12sub load_all {
13    my $class = shift;
14    $class->rescan_modules;
15
16    for my $mod (keys %modules) {
17        if(!defined eval "use BarnOwl::Module::$mod") {
18            BarnOwl::error("Unable to load module $mod: \n$@\n") if $@;
19        }
20    }
21
22    $BarnOwl::Hooks::startup->add(\&register_keybindings);
23}
24
25sub rescan_modules {
26    PAR::reload_libs();
27    PAR->import(BarnOwl::get_data_dir() . "/modules/*.par");
28    PAR->import(BarnOwl::get_config_dir() . "/modules/*.par");
29    my @modules;
30
31    %modules = ();
32
33    my @moddirs = ();
34    push @moddirs, BarnOwl::get_data_dir() . "/modules";
35    push @moddirs, BarnOwl::get_config_dir() . "/modules";
36   
37    for my $dir (@moddirs) {
38        opendir(my $dh, $dir) or next;
39        while(defined(my $f = readdir($dh))) {
40            next if $f =~ /^\./;
41            if(-f "$dir/$f" && $f =~ /^(.+)\.par$/) {
42                $modules{$1} = 1;
43            } elsif(-d "$dir/$f" && -d "$dir/$f/lib") {
44                unshift @INC, "$dir/$f/lib" unless grep m{^$dir/$f/lib$}, @INC;
45                $modules{$f} = 1;
46            }
47        }
48        @modules = grep /\.par$/, readdir($dh);
49        closedir($dh);
50        for my $mod (@modules) {
51            my ($class) = ($mod =~ /^(.+)\.par$/);
52            $modules{$class} = 1;
53        }
54    }
55}
56
57sub reload_module {
58    my $class = shift;
59    my $module = shift;
60
61    $class->rescan_modules();
62
63    for my $m (keys %INC) {
64        delete $INC{$m} if $m =~ m{^BarnOwl/Module/$module};
65    }
66
67    local $SIG{__WARN__} = \&squelch_redefine;
68    if(!defined eval "use BarnOwl::Module::$module") {
69        BarnOwl::error("Unable to load module $module: \n$@\n") if $@;
70    }
71}
72
73sub reload_cmd {
74    my $class = shift;
75    shift; # Command
76    my $module = shift;
77    unless(defined($module)) {
78        die("Usage: reload [MODULE]");
79    };
80    $class->reload_module($module);
81}
82
83sub register_keybindings {
84    BarnOwl::new_command('reload-modules', sub {BarnOwl::ModuleLoader->reload}, {
85                           summary => 'Reload all modules',
86                           usage   => 'reload-modules',
87                           description => q{Reloads all modules located in ~/.owl/modules and the system modules directory}
88                          });
89    BarnOwl::new_command('reload', sub {BarnOwl::ModuleLoader->reload_cmd(@_)}, {
90                           summary => 'Reload one module',
91                           usage   => 'reload [MODULE]',
92                           description => q{Reloads a single module located in ~/.owl/modules or the system modules directory}
93                          });
94}
95
96sub reload {
97    my $class = shift;
98    for my $m (keys %INC) {
99        delete $INC{$m} if $m =~ m{^BarnOwl/};
100    }
101    # Restore core modules from perlwrap.pm
102    $INC{$_} = 1 for (qw(BarnOwl.pm BarnOwl/Hooks.pm
103                         BarnOwl/Message.pm BarnOwl/Style.pm));
104
105    local $SIG{__WARN__} = \&squelch_redefine;
106    $class->load_all;
107    $BarnOwl::Hooks::startup->run(1);
108    BarnOwl::startup() if *BarnOwl::startup{CODE};
109}
110
111sub squelch_redefine {
112    my $warning = shift;
113    warn $warning unless $warning =~ /^Subroutine .+ redefined at/;
114}
115
1161;
Note: See TracBrowser for help on using the repository browser.