Using a plugin architecture for extensibility

This commit is contained in:
Mahesh Asolkar 2013-02-26 01:18:30 -08:00
parent 88e2659c6d
commit 1632ab91bf
6 changed files with 178 additions and 142 deletions

27
Licenses.pm Normal file
View File

@ -0,0 +1,27 @@
package Licenses;
use Module::Pluggable instantiate => 'new', search_path => "Licenses";
use Data::Dumper;
sub new {
return bless {}, shift;
}
sub get_licenses {
my ($self, $app) = @_;
print "Plugins\n";
foreach my $plugin ($self->plugins()) {
my $stub = $plugin->{'header'};
$stub =~ s/###DESCRIPTION###/$app->{'options'}->{'about'}/;
$stub =~ s/###DATE###/$app->{'options'}->{'date'}/;
$stub =~ s/###NAME###/$app->{'options'}->{'user'}/;
$app->{'licenses'}->{$plugin->{'name'}} = {
'pretty_name' => $plugin->{'pretty_name'},
'header_stub' => $stub
};
}
}
1;

View File

@ -1,3 +1,10 @@
package Licenses::GPLV2;
sub new {
return bless {
'name' => 'gpl_v3',
'pretty_name' => 'GPL v3',
'header' => qq {
###DESCRIPTION###
Copyright (C) ###DATE### ###NAME###
@ -13,3 +20,12 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
}
}, shift;
}
sub get_license_stub {
my ($self) = @_;
}
1;

View File

@ -1,3 +1,10 @@
package Licenses::MIT;
sub new {
return bless {
'name' => 'mit',
'pretty_name' => 'MIT',
'header' => qq {
Copyright (c) ###DATE### ###NAME###
Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -17,3 +24,8 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
}
}, shift;
}
1;

129
licapp.pl
View File

@ -1,129 +0,0 @@
#!/bin/env perl
use strict;
use warnings;
use File::Find;
use File::Basename;
use FileHandle;
use Data::Dumper;
use Getopt::Long;
use Cwd;
# Application configuration and state storage
my $app = {};
# Defaults
$app->{'options'}->{'directory'} = getcwd;
$app->{'options'}->{'license'} = 'mit';
$app->{'options'}->{'user'} = $ENV{'USER'};
$app->{'options'}->{'date'} = (localtime(time))[5] + 1900;
$app->{'options'}->{'about'} = "This is an open-source software";
$app->{'state'}->{'license_stub'} = "NON EXISTANT";
$app->{'state'}->{'app_dir'} = dirname($0);
# Command line options
my $correct_usage = GetOptions (
'directory=s' => \$app->{'options'}->{'directory'},
'license=s' => \$app->{'options'}->{'license'},
'about=s' => \$app->{'options'}->{'about'},
'user=s' => \$app->{'options'}->{'user'},
'date=s' => \$app->{'options'}->{'date'},
);
setup_license_pretty_names($app);
setup_filetype_comment_mapping($app);
setup_license_stub($app);
print "Applying '"
. $app->{'license_pretty_names'}->{$app->{'options'}->{'license'}}
. "' license to files in '"
. $app->{'options'}->{'directory'}
. "' directory\n\n";
print "Copyright: Copyright (C) "
. $app->{'options'}->{'date'}
. " " . $app->{'options'}->{'user'}
. "\n\n";
print "About: " . $app->{'options'}->{'about'}
. "\n\n";
print "Stub:\n-----\n$app->{'state'}->{'license_stub'}\n-----\n";
find (sub {
find_files($app, ${File::Find::name}, $_)
}, $app->{'options'}->{'directory'});
#
# Subroutines
#
sub find_files {
my ($app, $file, $name) = @_;
#
# Opportunity to filter any file types befrore any processing starts
#
handle_files ($app, $file, $name);
}
sub handle_files {
my ($app, $file, $name) = @_;
my $rh = new FileHandle ($name);
my @contents = <$rh>;
print "Handling... $file\n";
if ((defined $contents[0]) && ($contents[0] =~ /^\s*#!/)) {
print " ... has #! line\n";
}
}
sub setup_license_stub {
my ($app) = @_;
my $header_file = $app->{'state'}->{'app_dir'}
."/licenses/"
. $app->{'options'}->{'license'} . ".header";
if (-e $header_file) {
my $rh = new FileHandle ($header_file);
$app->{'state'}->{'license_stub'} = do {local $/; <$rh>};
$app->{'state'}->{'license_stub'} =~
s/###DESCRIPTION###/$app->{'options'}->{'about'}/;
$app->{'state'}->{'license_stub'} =~
s/###DATE###/$app->{'options'}->{'date'}/;
$app->{'state'}->{'license_stub'} =~
s/###NAME###/$app->{'options'}->{'user'}/;
}
else {
warn "[WARN] License Header '$header_file' does not exist";
}
}
sub setup_license_pretty_names {
my ($app) = @_;
$app->{'license_pretty_names'} = {
'mit' => 'MIT',
'gpl_v1' => 'GPL v1',
'gpl_v2' => 'GPL v2',
'gpl_v3' => 'GPL v3',
'apache_v2' => 'Apache v2',
'apache_v1' => 'Apache v1'
};
}
sub setup_filetype_comment_mapping {
my ($app) = @_;
$app->{'filetype_commants'} = {
'.pl' => '#',
'.rb' => '#',
'.erb' => ['<!--', '-->'],
'.html' => ['<!--', '-->'],
'.v' => '//',
'.sv' => '//',
'.vr' => '//'
};
}

View File

@ -1,13 +0,0 @@
Copyright ###DATE### ###NAME###
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

123
licensor.pl Executable file
View File

@ -0,0 +1,123 @@
#!/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin";
use File::Find;
use File::Basename;
use FileHandle;
use Data::Dumper;
use Getopt::Long;
use Cwd;
use File::Glob ':globally';
use Licenses;
# Application configuration and state storage
my $app = {};
# Defaults
$app->{'options'}->{'directory'} = getcwd;
$app->{'options'}->{'license'} = 'mit';
$app->{'options'}->{'user'} = $ENV{'USER'};
$app->{'options'}->{'date'} = (localtime(time))[5] + 1900;
$app->{'options'}->{'about'} = "This is an open-source software";
$app->{'state'}->{'license_stub'} = "NON EXISTANT";
$app->{'state'}->{'app_dir'} = dirname($0);
# Command line options
my $correct_usage = GetOptions (
'directory=s' => \$app->{'options'}->{'directory'},
'license=s' => \$app->{'options'}->{'license'},
'about=s' => \$app->{'options'}->{'about'},
'user=s' => \$app->{'options'}->{'user'},
'date=s' => \$app->{'options'}->{'date'},
);
setup_licenses($app);
setup_filetype_comment_mapping($app);
print "Applying '"
. $app->{'licenses'}->{$app->{'options'}->{'license'}}->{'pretty_name'}
. "' license to files in '"
. $app->{'options'}->{'directory'}
. "' directory\n\n";
print "Copyright: Copyright (C) "
. $app->{'options'}->{'date'}
. " " . $app->{'options'}->{'user'}
. "\n\n";
print "About: " . $app->{'options'}->{'about'}
. "\n\n";
print "Stub:\n-----\n"
. $app->{'licenses'}->{$app->{'options'}->{'license'}}->{'header_stub'}
. "\n-----\n";
find (sub {
find_files($app, ${File::Find::name}, $_)
}, $app->{'options'}->{'directory'});
#
# Subroutines
#
sub find_files {
my ($app, $file, $name) = @_;
#
# Opportunity to filter any file types befrore any processing starts
#
handle_files ($app, $file, $name);
}
sub handle_files {
my ($app, $file, $name) = @_;
return unless -f $name;
my($filename, $directories, $suffix) = fileparse($file, qr/\.[^.]*/);
if (exists $app->{'filetype_comments'}->{$suffix}) {
my $rh = new FileHandle ($name);
my @contents = <$rh>;
print "Handling... $filename - $directories - $suffix\n";
if ((defined $contents[0]) && ($contents[0] =~ /^\s*#!/)) {
print " ... has #! line\n";
}
}
else {
print "[ALERT] Don't know how to comment in file with '$suffix' extension\n";
}
}
sub setup_licenses {
my ($app) = @_;
my $licenses = new Licenses;
$licenses->get_licenses($app);
print "[INFO] Imported "
. join (', ', keys %{$app->{'licenses'}})
. " licenses\n";
}
sub setup_filetype_comment_mapping {
my ($app) = @_;
$app->{'filetype_comments'} = {
'.pl' => '#',
'.rb' => '#',
'.erb' => ['<!--', '-->'],
'.html' => ['<!--', '-->'],
'.css' => ['/*', '*/'],
'.coffee' => '#',
'.js' => '//',
'.scss' => '//',
'.v' => '//',
'.sv' => '//',
'.vr' => '//'
};
}