File Coverage

lib/Kwiki/Command.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Kwiki::Command;
2 1     1   2191 use Spoon::Command -Base;
  0            
  0            
3              
4             sub handle_new {
5             $self->assert_directory(shift, 'Kwiki');
6             $self->add_new_default_config;
7             $self->install('files');
8             $self->install('config');
9             $self->create_registry;
10             # XXX a method should return this list of plugin class_ids
11             $self->install('display');
12             $self->install('edit');
13             $self->install('formatter');
14             $self->install('users');
15             $self->install('pages');
16             $self->install('theme');
17             $self->install('toolbar');
18             $self->install('status');
19             $self->install('widgets');
20             io('plugin')->mkdir;
21             $self->set_permissions;
22             warn "\nKwiki software installed! Point your browser at this location.\n\n";
23             }
24              
25             sub handle_new_view {
26             $self->assert_directory(shift, 'kwiki view');
27             die "Parent directory does not look like a Kwiki installation"
28             unless -e '../plugins';
29             require Cwd;
30             my $home = Cwd::cwd();
31             $home =~ s/.*\///;
32             for my $file (io->updir->all) {
33             my $name = $file->filename;
34             next if $name eq '.htaccess';
35             next if $name eq 'plugins';
36             next if $name eq 'registry.dd';
37             next if $name eq $home;
38             io->link($name)->symlink($file->name);
39             }
40             $self->create_new_view_plugins;
41             $self->handle_update;
42             print <
43              
44             New view created. Now edit the $home/plugins file and run
45             'kwiki -update' in the '$home' subdirectory.
46             END
47             }
48              
49             sub create_new_view_plugins {
50             io('plugins')->print(<
51             # You can either list all the plugins you want manually, or put '+' and '-' in
52             # front of the plugins you want to add/remove from ../plugins respectively.
53             #
54             # Example:
55             #
56             # -Kwiki::Edit
57             # +Kwiki::Favorites
58             # +Kwiki::Weather
59             END
60             }
61              
62             sub assert_directory {
63             chdir io->dir(shift || '.')->assert->open->name;
64             my $noun = shift;
65             die "Can't make new $noun in a non-empty directory\n"
66             unless io('.')->empty;
67             }
68              
69             sub add_new_default_config {
70             $self->hub->config->add_config(
71             {
72             display_class => 'Kwiki::Display',
73             edit_class => 'Kwiki::Edit',
74             files_class => 'Kwiki::Files',
75             theme_class => 'Kwiki::Theme::Basic',
76             toolbar_class => 'Kwiki::Toolbar',
77             status_class => 'Kwiki::Status',
78             widgets_class => 'Kwiki::Widgets',
79             }
80             );
81             }
82              
83             sub install {
84             my $class_id = shift;
85             my $object = $self->hub->$class_id
86             or return;
87             return unless $object->can('extract_files');
88             my $class_title = $self->hub->$class_id->class_title;
89             $self->msg("Extracting files for $class_title:\n");
90             $self->hub->$class_id->quiet($self->quiet);
91             $self->hub->$class_id->extract_files;
92             $self->msg("\n");
93             }
94              
95             sub is_kwiki_dir {
96             my $dir = shift || '.';
97             -d "$dir/plugin" and -f "$dir/registry.dd";
98             }
99              
100             sub handle_update {
101             chdir io->dir(shift || '.')->assert->open . '';
102             die "Can't update non Kwiki directory!\n"
103             unless -d 'plugin';
104             $self->create_registry;
105             $self->install($_) for $self->all_class_ids;
106             $self->set_permissions;
107             }
108              
109             sub handle_update_all {
110             my @dirs = (io->curdir, io->curdir->All_Dirs);
111             while (my $dir = shift @dirs) {
112             next unless $self->is_kwiki_dir($dir);
113             $self->msg('Updating ', $dir->absolute->pathname, "\n");
114             $dir->chdir;
115             system("kwiki -quiet -update");
116             }
117             }
118              
119             sub all_class_ids {
120             my @all_modules;
121             for my $key (keys %{$self->hub->config}) {
122             push @all_modules, $self->hub->config->{$key}
123             if $key =~ /_class/;
124             }
125             push @all_modules, @{$self->hub->config->{plugin_classes} || []};
126             map {
127             eval "require $_; 1"
128             ? $_->can('extract_files')
129             ? do {
130             my $class_id = $_->class_id;
131             $self->hub->config->add_config({"${class_id}_class" => $_});
132             ($_->class_id)
133             }
134             : ()
135             : ();
136             } @all_modules;
137             }
138              
139             sub handle_add {
140             $self->update_plugins('+', @_);
141             }
142              
143             sub handle_remove {
144             $self->update_plugins('-', @_);
145             }
146              
147             sub update_plugins {
148             die "This operation must be performed inside a Kwiki installation directory"
149             unless -f $self->hub->config->plugins_file;
150             my $mode = shift;
151             return $self->usage unless @_;
152             my $plugins_file = $self->hub->config->plugins_file;
153             my $plugins = io($plugins_file);
154             my @lines = $plugins->chomp->slurp;
155             for my $module (@_) {
156             eval "require $module;1" or die $@ or
157             ($module = "Kwiki::$module" and eval "require $module;1") or
158             die "Invalid module '$module'";
159             if ($mode eq '+') {
160             next if grep /^$module$/, @lines;
161             push @lines, $module;
162             next;
163             }
164             @lines = grep {$_ ne $module} @lines;
165             }
166             $plugins->println($_) for @lines;
167             $plugins->close;
168             $self->hub->config->add_plugins_file($plugins_file);
169             $self->handle_update;
170             }
171              
172             sub handle_install {
173             die "This operation must be performed inside a Kwiki installation directory"
174             unless -f $self->hub->config->plugins_file;
175             return $self->usage unless @_;
176             require Cwd;
177             $self->cpan_setup;
178             my @modules = @_;
179             for my $module (@_) {
180             $self->fake_install($module);
181             my $home = Cwd::cwd();
182             my $rc = CPAN::Shell->expand('Module', $module);
183             if (not defined $rc) {
184             die "WARNING - Can't install $module\nStopping...\n";
185             }
186             $rc->install;
187             chdir $home;
188             }
189             $self->update_plugins('+', @modules);
190             }
191              
192             sub cpan_setup {
193             no warnings;
194             require CPAN;
195             # require CPAN::Config;
196             my $lib = io->dir('lib')->absolute;
197             $ENV{PERL_MM_OPT} = "INSTALLSITELIB=$lib PREFIX=$lib"
198             if $lib->exists;
199             CPAN::Config->load;
200             $CPAN::Config_loaded = 1;
201             my $cpan_dir = io->dir('.cpan')->rel2abs;
202             $CPAN::Config->{cpan_home} =
203             $CPAN::Config->{build_dir} = $cpan_dir;
204             $CPAN::Config->{keep_source_where} =
205             io->catdir($cpan_dir, 'sources')->name;
206             }
207              
208             sub fake_install {
209             return unless -d 'lib';
210             my $module = shift;
211             $module =~ s/::/\//g;
212             $module .= '.pm';
213             my $file = io->catfile('lib', $module);
214             $file->assert->touch
215             unless -f $file->name;
216             }
217              
218             sub handle_compress {
219             require Spoon::Installer;
220             Spoon::Installer->new->compress_lib(@_);
221             }
222              
223             sub set_permissions {
224             my $umask = umask 0000;
225             chmod 0777, qw(database plugin);
226             chmod 0666, qw(database/HomePage);
227             chmod 0755, qw(index.cgi);
228             umask $umask;
229             }
230              
231             sub create_registry {
232             my $registry = $self->hub->registry;
233             my $registry_path = $registry->registry_path;
234             $self->msg("Generating Kwiki Registry '$registry_path'\n");
235             $registry->update;
236             if ($registry->validate) {
237             $registry->write;
238             }
239             $self->hub();
240            
241             $self->hub->registry->load;
242             }
243              
244             sub usage {
245             warn <command_usage(" kwiki -%-20s # %s\n");
246             usage:
247             kwiki -new [path] # Generate a new Kwiki
248             kwiki -update [path] # Update an existing Kwiki
249             kwiki -add Kwiki::Foo # Add a plugin
250             kwiki -remove Kwiki::Foo # Remove a plugin
251             kwiki -install Kwiki::Foo # Download and install a plugin
252             kwiki -new_view [subdir] # Create a new view under an existing Kwiki
253             kwiki -update_all # Update all Kwiki dirs under current dir
254             END
255             }
256              
257             __DATA__