Hello Monk::Thomas
Your idea is brilliant, it will make newscript much clearer and easier to maintain!
Although, right now I'm working on an interactive clustering facility, a way to regroupe modules or libraries under tags, or clusters.
It's still a stand-alone program, I haven't added it to newscript yet and once I get it implemented I will work on a way to make, remove and choose cluster from the command line directly
It's operating on a file, .cluster, created in the user's $HOME directory. Although a little cryptic to read, it's possible to edit the file directly to add, remove and edit cluster as long as the ;name;modules, syntax is followed (both semi colons arround name and trailing coma after every module is important). As of right now, it's not possible to edit interactively an already made cluster. At the moment, only perl module can be clustered.
It's a work in progress but if you want, have a try and tell me what you think of it ;)
As of the many "why the hell did he do it this way oO " that you gonna ask yourself.. well I did with what I knew :P.
Thanks for you feedback ! :)
#!/usr/bin/perl
use warnings;
use strict;
my ($cmd,$usercmd);
my $cfile_content = '';
my $command = 1;
my $home = $ENV{HOME};
chomp ( my $cfile = "$home/.cluster") ;
my ( @namelist, @modname);
my %nammod;
my $timedone = 0;
my $doneit = 0;
my $tempfile = "/$home/tmp_cluster";
# Greetings
print "\n\n\t\t\tWelcome to the Cluster Facility\n";
_filecheck();
_cluster_help();
# We need some vars that are setup in this sub
_make_list();
_input();
# Get command from user
sub _input {
print "\n\nCommand -> ";
chomp ($usercmd = <STDIN>);
_ineed($usercmd);
}
# Main menu
sub _ineed {
$cmd = shift ;
# Make a list of registered cluster
if ($cmd =~ /list/i) {
_thelist();
_input();
}
# Add a new cluster to /$home/.cluster
elsif ($cmd =~ /add/i) {
_add();
_input();
}
# Remove a cluster from /$home/.cluster
elsif ($cmd =~ /remove/i ) {
_removec();
_input();
}
# Edit a cluster using it's name
elsif ($cmd =~ /edit/i) {
# _edit();
print "\n\n\nNot Available Yet\n\n\n";
_input();
}
# Call the usage sub
elsif ($cmd =~ /help/i ) {
_cluster_help();
_input();
}
# Exit the program
elsif ($cmd =~ /(exit|quit)/i ) {
exit;
}
# Else you're lost, print usage for you
else {
print "\n\n//Invalid command; Take a look a this:\n";
_cluster_help();
_input();
}
}
# to add a cluster:
sub _add {
# call on _filecheck to verify if /$home/.cluster exist
# skip if we've done the check once already.
my $addclus = 1;
print "\n\n\t\t\t\tAdd a Cluster:\n";
while ($addclus) {
my @cmodules;
# Get cluster name from user
print "\t\tFor a list of registered cluster use 'list',\n";
print "\t\t'return' to get back to main menu, 'exit' to leave.
+\n\n\n";
print "\nName of your new cluster: ";
chomp (my $cname = <STDIN>);
# Test the input, return 2 if everything is good
# return 1 if a test fails, return 3 if 'list' was input
my $checkres = input_check($cname);
print "\$checkres is $checkres\n\n";
if ($checkres == 1) {
print "//problem inside input_check\n\n";
redo;
} elsif ($checkres == 3) {
redo;
}
# check for duplicates
for my $uname (@namelist) {
return _add() unless ($uname !~ m/\Q$cname/);
}
print "Which module you want in the $cname cluster?:\n";
# get modules from user
print "Module name: ";
while (<>) {
if ($_ =~ /done/i) {
last;
} else {
my $modcopy = $_;
my $test = input_check($modcopy);
if ($test == 2) {
push @cmodules, $_;
} elsif (($test == 1) || ($test == 3)) {
print "Module name: ";
next;
}
}
print "Module name: ";
}
# write cluster name; followed by each modules, to /$home/.clu
+ster
open (my $CLUS, '>>', $cfile);
print $CLUS ";$cname;";
for my $mods (@cmodules) {
chomp $mods;
# append a coma after each module
print $CLUS "$mods,";
}
close $CLUS;
# ask user for more cluster, if no call _input();
print "\nAdd another cluster? [yes/no]: ";
chomp (my $answer = <STDIN>);
if ($answer =~ /yes|y/) {
@cmodules = undef;
redo;
} else {
# if answer is no, we're done here
$addclus--;
}
}
}
# Used to modify existing cluster entry.
# Not sure how to edit modules of a given cluster yet.
#sub _edit {
# my $editit = 1;
# while ($editit) {
# print "\n\nWhich Cluster would you like to modify?: ";
# chomp (my $modify = <STDIN>);
# if ($modify =~ /return/i) {
# print "\nBack to main menu.\n";
# return _input();
# } elsif ($modify =~ /list/i) {
# _thelist();
# }
# for my $name (@namelist) {
# if ($name =~ m/\Q$modify/) {
# print "\nWe editing -> $modify\n";
# print "Name of Cluster: $name. Modules of $name: $namm
+od{$name}\n\n";
#
# }
# }
# print "Edit other Clusters? [yes/no]: ";
# chomp (my $yesno = <STDIN>);
# if ($yesno =~ /yes|y/i) {
# redo;
# } else {
# $editit--;
# }
# }
#}
# Used to remove whole existing clusters.
sub _removec {
my $keepgoing = 1;
while ($keepgoing == 1) {
my $chkinhash;
my $newcfile = '';
# Print a list of Clusters
_thelist();
print "Cluster to remove: ";
# Ask user which Cluster he wishes removed
chomp (my $remclus = <STDIN>);
my $testres = input_check($remclus);
if ($testres == 1) {
print "Syntax error\n";
redo;
} elsif ($testres == 2){
} elsif ($testres == 3){
redo;
}
# Checks if the input name matches one from namelist
for my $name (@namelist) {
# If yes print a warning
if ($name =~ m/\Q$remclus/) {
print "\$name is \$remclus: $name == $remclus\n";
$chkinhash = $nammod{$remclus};
print "\$chkinhash is: $chkinhash\n";
# If it doesn't match, append it to $newcfile to rebui
+ld cfile
} else {
if ($newcfile) {
$newcfile = "$newcfile;$name;$nammod{$name}";
} else {
$newcfile = ";$name;$nammod{$name}";
}
}
}
print "\n\n\$newcfile is $newcfile\n\n";
unlink "$cfile";
open (my $NCLUS, '>', $cfile);
print $NCLUS "$newcfile";
close $NCLUS;
$keepgoing--;
}
}
# This is done once every time the program run
sub _filecheck {
# check if .cluster file exist
if (-e $cfile) {
# If it does, make sure it's a file and not something wierd
if (-f $cfile) {
# Check if you have read and write permission
if (-r -w $cfile) {
# you are all good
print "All checks are good\n";
# We don't wanna redo these test.
# $doneit++;
# Make a list of cluster name
# return _make_list();
} else { # if you can't read or write cfile, we've got a p
+roblem
print "You can't read nor write $cfile\n";
exit;
}
} else { # if cfile isn't a plain file, we've got a problem
print "$cfile is not a plain file\n";
exit;
}
} else { # if file doesn't exist, print a warning and continue
print "$cfile doesn't exist\n";
}
}
# Make a hash to map cluster names to their modules
sub _make_list {
# Read in $home/.cluster file
open (my $CLUS, '<', $cfile);
while (<$CLUS>) {
chomp;
# If .cluster is single lined, assign $_ to it
if ($cfile_content eq '') {
$cfile_content = $_;
# If .cluster is multi lined, apend $_ to clusterfile_content
+
} else {
$cfile_content = "$cfile_content$_";
}
}
close $CLUS;
# use ';' to separate cluster names and modules. Put the result in
+ array
my @splitted_file = split /;/, $cfile_content;
# Discard the first entry, not sure where it gets the whitespace
shift @splitted_file;
# set up the hash. Keys are the names, values the modules
%nammod = @splitted_file;
# Assign keys and value to their respective array for later use
@modname = values %nammod;
@namelist = keys %nammod;
# unset variables to get a new list everytime
$cfile_content = '';
$timedone++
}
sub _thelist {
_make_list();
print "\n\t\tThere's the list of registered Clusters:\n";
print "Cluster_Name => Modules, \n\n";
# sort Cluster by name and print
for my $key (sort keys %nammod) {
my $value = $nammod{$key};
print "$key => $value\n";
}
print "\n\n";
}
# Validates input
sub input_check {
chomp (my $totest = shift);
# (2) Check for punctuation
if ($totest =~ /^(\w)+(::(\w)+)*?[^[:punct:]]$/ ) {
print "//(2); pass\n";
# Check if input match list
if ($totest !~ /list/i) {
print "//(3): pass\n";
# Check if input match return
if ($totest !~ /return/i) {
print "//(4): pass\n";
if ($totest !~ /exit|quit/i) {
print "//(5): pass\n";
return(2);
} else { # match exit or quit
print "//(5): Failed: $totest: Leaving\n";
exit;
} else { # match return
print "//(4): Failed: $totest: Going back to main menu
+\n";
_input();
}
} else { # match list
print "//(3): List\n";
_thelist();
return(3);
}
} else { # match punctuation
print "\n//(2): Failed: Contain bad characters\n";
print "//No punctuation allowed\n\n";
return(1);
}
}
sub _cluster_help {
print<<EOF;
Newscript.pl: Cluster Facility
You can use this facility to group your most frenquently
used modules.
For exemple, you select Perl and a name,
inet, then you can make a new cluster that contain your module
+s:
In this case only 2 modules LWP::* and CGI::*.
Next time you create a newscript, you can use the following:
newscript.pl [--cluster=inet] [name]
and newscript will create a template with the apropriate
language and your clustered modules.
Options:
-list Print a list of existing cluster and their conten
+t.
-add Add a new cluster.
-remove Remove an existing cluster.
-edit Remove a modules from within an existing cluster.
-help Print this message.
-exit Exit program.
-quit Exit program.
EOF
}