File Coverage

blib/lib/Goo/Thing/goo/Maker.pm
Criterion Covered Total %
statement 27 132 20.4
branch 0 28 0.0
condition n/a
subroutine 9 15 60.0
pod 6 6 100.0
total 42 181 23.2


line stmt bran cond sub pod time code
1             package Goo::Thing::goo::Maker;
2              
3             ###############################################################################
4             # Nigel Hamilton
5             #
6             # Copyright Nigel Hamilton 2005
7             # All Rights Reserved
8             #
9             # Author: Nigel Hamilton
10             # Filename: Goo::Thing::goo::Maker.pm
11             # Description: Make .goo configuration file
12             #
13             # Date Change
14             # -----------------------------------------------------------------------------
15             # 15/06/2005 Auto generated file
16             # 15/06/2005 Need to make new goo files
17             # 06/11/2005 Added method: writeConfigFile
18             # 08/11/2005 Added method: tableMaker
19             #
20             ###############################################################################
21              
22 1     1   6425 use strict;
  1         6  
  1         37  
23              
24 1     1   8 use Goo::Header;
  1         2  
  1         19  
25 1     1   5 use Goo::Object;
  1         4  
  1         22  
26 1     1   7 use Goo::Prompter;
  1         27  
  1         22  
27 1     1   5 use Goo::Database;
  1         2  
  1         26  
28 1     1   5 use Goo::TextTable;
  1         2  
  1         27  
29 1     1   6 use Goo::ConfigFile;
  1         3  
  1         31  
30 1     1   5 use Goo::TextEditor;
  1         2  
  1         30  
31              
32 1     1   4 use base qw(Goo::Object);
  1         2  
  1         1831  
33              
34             my $GOO_ROOT = "$ENV{HOME}/.goo/things/goo/";
35              
36              
37             ###############################################################################
38             #
39             # run - generate a goo file
40             #
41             ###############################################################################
42              
43             sub run {
44              
45 0     0 1   my ($this, $filename) = @_;
46              
47 0           my $prefix = get_prefix($filename);
48              
49 0           while (1) {
50              
51             # show the Maker header
52 0           Goo::Header::show($prefix, $filename);
53              
54 0           Goo::Prompter::say();
55 0           Goo::Prompter::say("Make a new Thing of type $prefix");
56 0           Goo::Prompter::say();
57              
58             # each type of Thing must have a title
59 0           my $title = Goo::Prompter::ask("Enter a title for $prefix Things?");
60 0 0         return unless ($title);
61              
62 0           my $description = Goo::Prompter::ask("Enter a description?");
63              
64             # get the location of these Things
65 0           my $thing_location =
66             Goo::Prompter::pick_one("Where are $prefix things found?",
67             ("file system", "database"));
68              
69 0           my @locations;
70             my $column_display_order;
71              
72             # grab Things out of the database
73 0 0         if ($thing_location eq "database") {
74              
75             # possibly return a connect string here.
76             # push(@locations, "");
77             # we need a table name
78             # create a table
79 0           make_table($prefix);
80              
81             # create a default display order
82              
83 0           $column_display_order = join(" ", Goo::Database::get_table_columns($prefix));
84              
85             } else {
86              
87             # grab the file locations for these Things
88 0           @locations = get_file_locations($prefix);
89              
90             }
91              
92             # get a list of commands and their handlers
93 0           my $commands = get_commands();
94              
95             # print Dumper($commands);
96             # write the config file to disk
97 0           write_config_file($filename, # the new .goo file
98             $title,
99             $description,
100             $commands,
101             $column_display_order,
102             @locations
103             );
104              
105              
106             # confirm the Thing is made. Long live the Thing.
107 0           Goo::Prompter::say();
108 0           Goo::Prompter::yell("Finished making a new Thing: $prefix.");
109 0           Goo::Prompter::say();
110              
111             # bail out if they want to
112 0 0         last unless Goo::Prompter::confirm("Make another type of Thing?", "N");
113              
114             # ask for what other Things they want to make
115 0           $filename = Goo::Prompter::ask("Enter the filename of the new Thing?");
116              
117             }
118              
119             }
120              
121              
122             ###############################################################################
123             #
124             # get_file_locations - find all the locations for this thing?
125             #
126             ###############################################################################
127              
128             sub get_file_locations {
129              
130 0     0 1   my ($suffix) = @_;
131              
132             # scan all the subdirectories for this type of Thing
133             # for version 1 we should ask - version 2 we should scan for them
134 0           my @locations =
135             Goo::Prompter::keep_asking("Enter a directory where $suffix files are found?");
136              
137             # add all the directory locations for this Thing
138 0           foreach my $location (@locations) {
139 0 0         unless (-e $location) {
140 0           Goo::Prompter::say("No location found: $location");
141 0 0         if (Goo::Prompter::confirm("Create a new location $location?")) {
142              
143             # may need to create a new directory
144 0           mkdir $location;
145             }
146             }
147             }
148              
149 0           return @locations;
150              
151             }
152              
153              
154             ###############################################################################
155             #
156             # get_commands - get a list of commands and action handlers for this thing
157             #
158             ###############################################################################
159              
160             sub get_commands {
161              
162 0     0 1   my ($this, $thing) = @_;
163              
164 0           Goo::Prompter::say();
165 0           Goo::Prompter::yell("Enter the actions for this Thing");
166              
167 0           my $config_file;
168              
169 0           while ($config_file = Goo::Prompter::ask("Inherit actions from another Thing?", "goo.goo")) {
170 0 0         unless ($config_file =~ /goo$/) {
171 0           Goo::Prompter::say("Please enter a .goo configuration file (e.g., goo.goo).");
172 0           next;
173             }
174 0           last;
175             }
176              
177             # get the top level goo.goo config file
178 0           my $goo_config = Goo::ConfigFile->new($config_file);
179              
180             # build a hash of commands
181 0           my $commands;
182              
183             # ask for global handlers
184 0           foreach my $command ($goo_config->get_commands()) {
185              
186             # keep the same action handler
187 0           $commands->{$command} =
188             Goo::Prompter::ask("Enter an action handler for $command?",
189             $goo_config->get_action_handler($command));
190              
191             }
192              
193             # ask for new handlers
194 0           while (my $new_command = Goo::Prompter::ask("Add a new action for this Thing?")) {
195              
196 0 0         if ($new_command !~ /\[[A-Z]\]/) {
197 0           Goo::Prompter::notify("Invalid command. " .
198             "Actions must include a capitalised letter in square brackets(e.g., [E]dit). Press a key. "
199             );
200 0           next;
201             }
202              
203             # get the action handler for this command
204 0           $commands->{$new_command} =
205             Goo::Prompter::ask("Enter an action handler for $new_command?");
206             }
207              
208 0           return $commands;
209              
210             }
211              
212              
213             ###############################################################################
214             #
215             # get_prefix - return a prefix for a file
216             #
217             ###############################################################################
218              
219             sub get_prefix {
220              
221 0     0 1   my ($filename) = @_;
222              
223 0           $filename =~ s/.*\///;
224 0           $filename =~ m/(.*)\..*$/;
225              
226 0           return $1;
227              
228             }
229              
230              
231             ###############################################################################
232             #
233             # write_config_file - write the file to disk
234             #
235             ###############################################################################
236              
237             sub write_config_file {
238              
239 0     0 1   my ($filename, $title, $description, $commands, $column_display_order, @locations) = @_;
240              
241 0           my $commands_table = Goo::TextTable->new();
242              
243             # go through all the commands
244 0           foreach my $key (keys %$commands) {
245              
246             # add the command_string to the file
247 0           $commands_table->add_row($key, " = ", $commands->{$key});
248             }
249              
250             # add this to the locations
251 0           my $locations_table = Goo::TextTable->new();
252              
253 0           foreach my $location (@locations) {
254 0           $locations_table->add_row("locations", " = ", $location);
255             }
256              
257              
258 0           my $database_string;
259              
260 0 0         if ($column_display_order) {
261              
262 0           my $table = $filename;
263 0           $table =~ s/\.goo//;
264              
265 0           $database_string = <<DATABASE;
266             # database details
267             table = $table
268             column_display_order = $column_display_order
269             DATABASE
270              
271             }
272              
273             # use string for interpolation
274 0           my $commands_string = $commands_table->render();
275 0           my $locations_string = $locations_table->render();
276              
277             # here is a template for all configuration files
278 0           my $file_contents = <<CONFIG;
279             ###############################################################################
280             #
281             # $filename - goo config file
282             #
283             ###############################################################################
284              
285             # what is this Thing?
286             title = $title
287             description = $description
288              
289             # actions and the programs that handle them
290             $commands_string
291              
292             # where is this Thing
293             $locations_string
294              
295             $database_string
296              
297             CONFIG
298              
299 0           Goo::FileUtilities::write_file($filename, $file_contents);
300              
301             }
302              
303              
304             ###############################################################################
305             #
306             # make_table - make a table
307             #
308             ###############################################################################
309              
310             sub make_table {
311              
312 0     0 1   my ($thing) = @_;
313              
314 0           my $table = $thing;
315 0           my $key = $thing . "id";
316              
317 0           Goo::Prompter::say(ucfirst($thing) . " Things will be stored in the $thing database table.");
318 0           Goo::Prompter::say("The primary key of the $thing table is $key.");
319              
320             # check if the table already exists?
321 0 0         if (Goo::Database::get_primary_key($thing)) {
322              
323             # do they want to drop it?
324 0 0         if (Goo::Prompter::confirm("Table $thing already exists. Delete $thing table?", "N")) {
325 0           Goo::Database::execute_sql("drop table $thing");
326 0           Goo::Prompter::say("$thing table deleted.");
327             } else {
328              
329             # bail out they're happy with the table already
330 0           Goo::Prompter::say("$thing table is unchanged.");
331 0           return;
332             }
333             }
334              
335             # start building the create statement
336 0           my @columns;
337              
338             # each database thing has a numerical id
339 0           push(@columns, "$key int not null primary key auto_increment ");
340              
341             # each Thing should have a title
342 0 0         if (Goo::Prompter::confirm("Add a title column to $table?", "Y")) {
343 0           push(@columns, "title varchar(100)");
344             }
345              
346             # and a description
347 0 0         if (Goo::Prompter::confirm("Add a description column to $table?", "Y")) {
348 0           push(@columns, "description text");
349             }
350              
351             # ask for more columns
352 0           while (my $column = lc(Goo::Prompter::ask("Add another column to the $table table?"))) {
353              
354 0           my $type =
355             Goo::Prompter::pick_one("What type is the column $column?",
356             qw(varchar text int date datetime));
357              
358 0 0         if ($type eq "varchar") {
359 0           my $length = Goo::Prompter::ask("Enter the length of the varchar?", "100");
360 0           $type = "varchar($length)";
361             }
362              
363             # more null handling etc.
364             # what about enum types?
365 0           push(@columns, "$column $type");
366              
367             }
368              
369             # make create statement
370 0           my $column_text = join(", \n ", @columns);
371              
372 0           my $sql_statement = "\n\ncreate table $table ($column_text) \n\n";
373              
374 0           while (Goo::Prompter::confirm("The SQL create statement: $sql_statement " . "Edit?", "N")) {
375              
376             # let the user edit the create statement
377 0           $sql_statement =
378             Goo::TextEditor::edit_string("\# Edit the SQL create statement $sql_statement");
379             }
380              
381 0 0         if (Goo::Prompter::confirm("Execute SQL?", "Y")) {
382              
383             # execute the SQL
384 0           Goo::Database::execute_sql($sql_statement);
385              
386             # let the user know about
387 0           Goo::Prompter::say();
388 0           Goo::Prompter::yell("$table table created.");
389 0           Goo::Prompter::say();
390              
391             } else {
392              
393             # let the user know about
394 0           Goo::Prompter::say();
395 0           Goo::Prompter::yell("$table table was not created.");
396 0           Goo::Prompter::say();
397              
398             }
399              
400             }
401              
402             1;
403              
404              
405             __END__
406              
407             =head1 NAME
408              
409             Goo::Thing::goo::Maker - Make a new Thing by creating a .goo configuration file
410              
411             =head1 SYNOPSIS
412              
413             # make a new Python Thing
414             shell> goo -m py.goo
415              
416             # make a new Thing for handling text files
417             shell> goo -m txt.goo
418              
419              
420             =head1 DESCRIPTION
421              
422             =head1 METHODS
423              
424             =over
425              
426             =item run
427              
428             generate a Goo file
429              
430             =item get_file_locations
431              
432             find all the locations for this Thing?
433              
434             =item get_commands
435              
436             get a list of commands and action handlers for this Thing
437              
438             =item get_prefix
439              
440             return a prefix for a file
441              
442             =item write_config_file
443              
444             write the file to disk
445              
446             =item make_table
447              
448             make a table
449              
450             =back
451              
452             =head1 AUTHOR
453              
454             Nigel Hamilton <nigel@trexy.com>
455              
456             =head1 SEE ALSO
457