source: perl/lib/BarnOwl/ModuleLoader.pm @ 5987370

debianrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 5987370 was 5987370, checked in by Nelson Elhage <nelhage@mit.edu>, 13 years ago
ModuleLoader.pm: Add a :reload command which reloads a single module
  • Property mode set to 100644
File size: 3.5 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    $BarnOwl::Hooks::startup->clear;
106    $BarnOwl::Hooks::getBuddyList->clear;
107    $BarnOwl::Hooks::mainLoop->clear;
108    $BarnOwl::Hooks::shutdown->clear;
109    $BarnOwl::Hooks::receiveMessage->clear;
110    local $SIG{__WARN__} = \&squelch_redefine;
111    $class->load_all;
112    $BarnOwl::Hooks::startup->run(1);
113    BarnOwl::startup() if *BarnOwl::startup{CODE};
114}
115
116sub squelch_redefine {
117    my $warning = shift;
118    warn $warning unless $warning =~ /^Subroutine .+ redefined at/;
119}
120
1211;
Note: See TracBrowser for help on using the repository browser.