Package: devscripts Version: 2.10.25 Followup-For: Bug #472199 -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA224
Dear devscripts developers, I'm not really a perl hacker but I did a try on adding this feature to licensecheck myself. It is *NOT* ready and does *NOT* do what it should. It just adds a possible way to output license information as requested by the copyright proposal. Well, I tried to comment on every sensefull line I've added so that you can clearly understand what I did. Furthermore I tried to not touch anything you wrote so I don't think that I broke anything. Although I added an option "createfile" my patch does not create a new copyright file. It just prints whatever could be put into such a file. I guess, doing the file handling is not the most difficult part of the job. :) I'd like to hear your comments on my patch. If you feel it is not worth working on it just tell me. I can stop everytime. Cheers, Hauke -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iE8DBQFIDJ+yGOp6XeD8cQ0RC09JAN9W/yU7VmN9KcSY66qJF+Qk4T0dYHASZxFy 7L31AN48ojn/OH0c2wgs7yncYLqReowZckrRiGjiqiYw =aNPf -----END PGP SIGNATURE-----
--- /usr/bin/licensecheck 2008-04-09 16:11:23.000000000 +0200 +++ licensecheck 2008-04-21 15:55:22.000000000 +0200 @@ -78,6 +78,10 @@ Also display copyright text found within the file +=item B<-f> B<--createfile> + +Create a new copyright file which is machine interpretable + =back =head1 CONFIGURATION VARIABLES @@ -160,6 +164,10 @@ my ($opt_help, $opt_version); my $def_lines = 60; +my $opt_createfile; +my $mr_licence; +my @mr_files; + # Read configuration files and then command line # This is boilerplate @@ -214,6 +222,7 @@ "copyright" => \$opt_copyright, "noconf" => \$opt_noconf, "no-conf" => \$opt_noconf, + "createfile|f" => \$opt_createfile, ) or die "Usage: $progname [options] filelist\nRun $progname --help for more details\n"; @@ -232,6 +241,7 @@ $opt_lines = $def_lines if not defined $opt_lines; my @files = (); +my %mr_files = (); my @find_args = (); my $files_count = @ARGV; @@ -257,6 +267,8 @@ } } +my @all_licenses; + while (@files) { my $file = shift @files; my $content = ''; @@ -295,10 +307,89 @@ $content =~ s#//##g; $content =~ tr/ //s; - print "$file: " . parselicense($content) . "\n"; - print " [Copyright: " . $copyright . "]\n" - if $copyright and $opt_copyright; - print "\n" if $opt_copyright; + # do machine readable stuff if $opt_createfile + if ( $opt_createfile ) { + # copyright output like: + # Copyright: year author + # year author + my $mr_copyright = join("\n\t", values %copyrights); + # if opt_createfile we get an array here + my @mr_licenses = parselicense($content); + # and join it to a string with an "or" statement since this is probably + # to most sensefull relation between two licenses of one file + my $mr_licensestring = join(" | ", @mr_licenses); + # create an array with all licenses used in every checked file + # we need this to output a License statement for each license at the end of + # the copyright file + push @all_licenses, @mr_licenses; + # have an array for each file with name, copyright and license + my @mr_file = ($file, $mr_copyright, $mr_licensestring); + # and push every file array to a global files array + push @mr_files, [ @mr_file ]; + } else { + print "$file: " . parselicense($content) . "\n"; + print " [Copyright: " . $copyright . "]\n" + if $copyright and $opt_copyright; + print "\n" if $opt_copyright; + } +} + +if ( $opt_createfile ) { + # what we have now: + # @mr_files = + # ARRAY ( + # [0] => ARRAY ( + # [0] => string filename + # [1] => string copyright + # [2] => string licenses (seperated by |) + # ) + # ) + # create an hash: + # %new_hash = + # HASH ( + # [ copyright_and_license_string ] => list_of_files_matching_this_copyright_and_license_(comma_sparated) + # ) + my %new_hash; + for ( my $i=0; $i<=$#mr_files; $i++ ) { + my @filedata = @{$mr_files[$i]}; + # string copyright_and_license: + # Copyright: year author (from above!) + # License: license1 | license2 (from above!) + my $mr_candl = "Copyright: " . $filedata[1] . "\nLicense: " . $filedata[2]; + if ( in_array ( $mr_candl, keys %new_hash ) ) { + $new_hash{$mr_candl} = $new_hash{$mr_candl} . ", " . $filedata[0]; + } else { + $new_hash{$mr_candl} = $filedata[0]; + } + } + # and then print the hash to output + # Files: comma separated list + # Copyright: ... + # License: ... + foreach my $key ( keys %new_hash ) { + print "Files: " . $new_hash{$key} . "\n"; + print $key . "\n\n"; + } + # output a License: line for each used license + my @uniq_licenses = keys %{{ map { $_ => 1 } @all_licenses }}; + foreach my $single_license ( @uniq_licenses ) { + # unless license is not known + if ( $single_license ne "UNKNOWN LICENSE" ) { + # we should ship some standard texts for GPL, LGPL and stuff... + print "License: $single_license\nType short form of license text here!\n\n" + } + } +} + +# small function (same as in_array in PHP ;-)) +sub in_array { + my $val = shift; + for my $elem ( @_ ) { + if ( $val eq $elem ) { + return 1; + } + } + return 0; } sub help { @@ -321,6 +412,7 @@ regular expression should be ignored when checking files (Default: '$default_ignore_regex') + --createfile, -f Create a machine interpretable copyright file Default settings modified by devscripts configuration files: $modified_conf_msg @@ -347,12 +439,18 @@ my $extrainfo = ""; my $license = ""; + # I added new vars for machine readable output to not break anything you wrote. + my @mr_licence; + my $mr_licenceinfo = ""; + if ($licensetext =~ /version ([^ ]+) (?:\(?only\)?.? )?(?:of the GNU General Public License )?as published by the Free Software Foundation/i or $licensetext =~ /GNU General Public License as published by the Free Software Foundation; version ([^ ]+) /i) { $gplver = " (v$1)"; + $mr_licenceinfo = "-$1"; } elsif ($licensetext =~ /either version ([^ ]+) of the License, or \(at your option\) any later version/) { $gplver = " (v$1 or later)"; + $mr_licenceinfo = "-$1+"; } if ($licensetext =~ /(?:675 Mass Ave|59 Temple Place|51 Franklin Steet|02139|02111-1307)/i) { @@ -365,78 +463,99 @@ if ($licensetext =~ /(All changes made in this file will be lost|DO NOT (EDIT|delete this file)|Generated by)/i) { $license = "GENERATED FILE"; + push(@mr_licence, "UNKNOWN LICENSE"); } if ($licensetext =~ /is free software. you can redistribute it and\/or modify it under the terms of the (GNU (Library|Lesser) General Public License|LGPL)/i) { $license = "LGPL$gplver$extrainfo $license"; + push(@mr_licence, "LGPL$mr_licenceinfo"); } if ($licensetext =~ /is free software.? you can redistribute it and\/or modify it under the terms of (?:version [^ ]+ (?:\(?only\)? )?of )?the GNU General Public License/i) { $license = "GPL$gplver$extrainfo $license"; + push(@mr_licence, "GPL$mr_licenceinfo"); } if ($licensetext =~ /is distributed.*terms.*GPL/) { $license = "GPL (unversioned/unknown version) $license"; + push(@mr_licence, "GPL"); } if ($licensetext =~ /This file is part of the .*Qt GUI Toolkit. This file may be distributed under the terms of the Q Public License as defined/) { $license = "QPL (part of Qt) $license"; + push(@mr_licence, "QPL"); } elsif ($licensetext =~ /may be distributed under the terms of the Q Public License as defined/) { $license = "QPL $license"; + push(@mr_licence, "QPL"); } if ($licensetext =~ /http:\/\/opensource\.org\/licenses\/mit-license\.php/) { $license = "MIT/X11 (BSD like) $license"; + push(@mr_licence, "MIT"); } elsif ($licensetext =~ /Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files \(the Software\), to deal in the Software/) { $license = "MIT/X11 (BSD like) $license"; + push(@mr_licence, "MIT"); } if ($licensetext =~ /Permission to use, copy, modify, and(\/or)? distribute this software for any purpose with or without fee is hereby granted, provided.*copyright notice.*permission notice.*all copies/) { $license = "ISC $license"; + push(@mr_licence, "other"); } if ($licensetext =~ /THIS SOFTWARE IS PROVIDED .*AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY/) { if ($licensetext =~ /All advertising materials mentioning features or use of this software must display the following acknowledge?ment.*This product includes software developed by/i) { $license = "BSD (4 clause) $license"; + push(@mr_licence, "BSD-4"); } elsif ($licensetext =~ /(The name of .*? may not|Neither the name of .*? nor the names of its contributors may) be used to endorse or promote products derived from this software/i) { $license = "BSD (3 clause) $license"; + push(@mr_licence, "BSD-3"); } elsif ($licensetext =~ /Redistributions of source code must retain the above copyright notice/i) { $license = "BSD (2 clause) $license"; + push(@mr_licence, "BSD-2"); } else { $license = "BSD $license"; + push(@mr_licence, "BSD"); } } if ($licensetext =~ /Mozilla Public License Version ([^ ]+)/) { $license = "MPL (v$1) $license"; + push(@mr_licence, "MPL-$1"); } if ($licensetext =~ /Released under the terms of the Artistic License ([^ ]+)/) { $license = "Artistic (v$1) $license"; + push(@mr_licence, "Artistic-$1"); } if ($licensetext =~ /This program is free software; you can redistribute it and\/or modify it under the same terms as Perl itself/) { $license = "Perl $license"; + push(@mr_licence, "Perl-$1"); } if ($licensetext =~ /under the Apache License, Version ([^ ]+) \(the License\)/) { $license = "Apache (v$1) $license"; + push(@mr_licence, "Apache-$1"); } if ($licensetext =~ /This source file is subject to version ([^ ]+) of the PHP license/) { $license = "PHP (v$1) $license"; + push(@mr_licence, "PHP-$1"); } if ($licensetext =~ /is in the public domain/i) { $license = "Public domain"; + push(@mr_licence, "PD"); } $license = "UNKNOWN" if (!length($license)); + @mr_licence = ("UNKNOWN LICENSE") if ( @mr_licence == 0 ); if ($licensetext !~ /copyright/i) { $license = "*No copyright* $license"; } + return @mr_licence if $opt_createfile; return $license; }