openwrt_deco_e4r/scripts/gen-relreport.pl

258 lines
8.4 KiB
Perl
Executable File

#!/usr/bin/env perl
# Copyright (c) 2014 The Linux Foundation. All rights reserved.
use strict;
use warnings;
use File::Temp qw/ :POSIX /;
use File::Copy;
use File::Basename;
use Excel::Writer::XLSX;
use Excel::Writer::XLSX::Utility;
use XML::Simple;
use FindBin;
use lib "$FindBin::Bin";
use metadata;
# %OPTS
# Hash of all the options provided through command line
my %OPTS;
# @CONFIGS
# Each element in CONFIGS contains a hash storing a config file content
my @CONFIGS;
# %QSDKPKGS
# Each element is a package from metadata enabled at least in one of the
# config files specified as an argument
my %QSDKPKGS;
sub load_config($) {
my $defconfig = shift;
my $dotconfig = tmpnam();
# Create a temporary file and extrapolate it with default values
copy( $defconfig, $dotconfig ) or die "Error when copying $defconfig: $!";
system( "./scripts/config/conf "
. "-D $dotconfig "
. "-w $dotconfig "
. "Config.in "
. "> /dev/null 2>&1" );
# Load the content in a config hash
my %config;
open FILE, "<$dotconfig" or return;
while (<FILE>) {
/^CONFIG_DEFAULT_(.+?)=y$/ and $config{$1} = { default => 1 };
/^CONFIG_PACKAGE_(.+?)=y$/ and $config{$1} = {};
}
close FILE;
$config{name} = basename( $defconfig, ".config" );
# Store the config hash in @CONFIGS and clean-up the FS
push( @CONFIGS, \%config );
unlink $dotconfig;
}
sub xref_packages() {
foreach my $config (@CONFIGS) {
foreach my $pkg ( keys %{$config} ) {
# Some config options created through "Package/config" still
# match the CONFIG_PACKAGE_ namespace so we'll ignore them here
# It's the case for LuCI, as an example
# (PACKAGE_luci-lib-core_source, PACKAGE_luci-lib-core_compiled...)
next if !exists( $package{$pkg} );
$QSDKPKGS{$pkg} = {
src => $package{$pkg}->{src},
name => $package{$pkg}->{name},
variant => $package{$pkg}->{variant},
# Feeds (subdir) is set to an empty string for packages in openwrt.git
subdir => $package{$pkg}->{subdir},
version => $package{$pkg}->{version},
description => $package{$pkg}->{description},
source => $package{$pkg}->{source},
}
unless exists( $QSDKPKGS{$pkg} );
# Linux & kmods version starts with the string <LINUX_VERSION>
# We remove this prefix here for better readability
$QSDKPKGS{$pkg}->{version} =~ s/^<LINUX_VERSION>-$/KERNEL/;
$QSDKPKGS{$pkg}->{version} =~ s/<LINUX_VERSION>[\+-](.+)/$1/;
push( @{ $QSDKPKGS{$pkg}->{configs} }, $config->{name} );
push( @{ $QSDKPKGS{$pkg}->{defconfigs} }, $config->{name} )
if ( exists( $config->{$pkg}->{default} ) );
}
}
}
sub write_output_xlsx($) {
my $filename = shift;
# Create a new workbook and add a worksheet
my $workbook = Excel::Writer::XLSX->new($filename);
my $worksheet = $workbook->add_worksheet();
# Init the worksheet (set columns width, create colors & formats)
$worksheet->set_column( 0, 1, 28 ); # Column A,B width set to 28
$worksheet->set_column( 2, 3, 14 ); # Column C,D width set to 14
$worksheet->set_column( 4, 4, 28 ); # Column E width set to 28
$worksheet->set_column( 5, 5, 14 ); # Column E width set to 14
$worksheet->set_column( 6, 6, 12 ); # Column F width set to 12
my $c_orange = $workbook->set_custom_color( 40, 247, 150, 70 );
my $c_green = $workbook->set_custom_color( 41, 196, 215, 155 );
my $c_red = $workbook->set_custom_color( 42, 218, 150, 148 );
my $f_title = $workbook->add_format(
align => 'center',
valign => 'vcenter',
bold => 1,
border => 2, # Continuous, Weight=2
bg_color => $c_orange,
);
my $f_data = $workbook->add_format(
align => 'center',
valign => 'vcenter',
border => 1,
);
my $f_green_data = $workbook->add_format(
align => 'center',
valign => 'vcenter',
border => 1,
bg_color => $c_green,
);
my $f_red_data = $workbook->add_format(
align => 'center',
valign => 'vcenter',
border => 1,
bg_color => $c_red,
);
my $f_desc = $workbook->add_format(
align => 'fill',
border => 1,
);
# Fill-in the titles
my @col = (
"SRC", "PACKAGE", "VARIANT", "FEED",
"TARBALL", "VERSION", "DESCRIPTION"
);
my $colid = 0;
foreach (@col) {
$worksheet->write( 0, $colid, $col[$colid], $f_title );
$colid++;
}
foreach ( sort { $a->{name} cmp $b->{name} } @CONFIGS ) {
$worksheet->write( 0, $colid, $_->{name}, $f_title );
$worksheet->set_column( $colid, $colid, 20 );
$colid++;
}
# Now we're ready. Let's start adding the data
my $row = 1;
my $prevpkg, my $start_merge = 0;
foreach my $cur (
sort { $QSDKPKGS{$a}->{src} cmp $QSDKPKGS{$b}->{src} }
keys %QSDKPKGS
)
{
my $col = 0;
my $curpkg = $QSDKPKGS{$cur};
$worksheet->write( $row, $col++, $curpkg->{src}, $f_data );
$worksheet->write( $row, $col++, $curpkg->{name}, $f_data );
$worksheet->write( $row, $col++, $curpkg->{variant}, $f_data );
$worksheet->write( $row, $col++, length( $curpkg->{subdir} )
? basename( $curpkg->{subdir} ) : "openwrt", $f_data );
$worksheet->write( $row, $col++, $curpkg->{source}, $f_data );
$worksheet->write_string( $row, $col++, $curpkg->{version}, $f_data )
unless !exists( $curpkg->{version} );
$worksheet->write( $row, $col++, $curpkg->{description}, $f_desc );
my %pkgconfigs = map { $_ => 1 } @{ $curpkg->{configs} };
foreach my $conf ( sort { $a->{name} cmp $b->{name} } @CONFIGS ) {
$worksheet->write( $row, $col++, "x", $f_green_data )
if exists( $pkgconfigs{ $conf->{name} } );
$worksheet->write_blank( $row, $col++, $f_red_data )
if !exists( $pkgconfigs{ $conf->{name} } );
}
# If the same package defines multiple BuildPackage/KernelPackage,
# we want to merge the src cells over multiple rows.
if ( $start_merge == 0
and exists( $prevpkg->{src} )
and $curpkg->{src} eq $prevpkg->{src} )
{
$start_merge = $row - 1;
}
if ( $start_merge != 0 and $curpkg->{src} ne $prevpkg->{src} ) {
# We want to merge the src, version and feeds columns
$worksheet->merge_range( $start_merge, 0, $row - 1, 0,
$prevpkg->{src}, $f_data );
$worksheet->merge_range( $start_merge, 3, $row - 1, 3,
length( $curpkg->{subdir} ) ? basename( $curpkg->{subdir} )
: "openwrt", $f_data );
$worksheet->merge_range( $start_merge, 4, $row - 1, 4,
$prevpkg->{source}, $f_data );
$worksheet->merge_range( $start_merge, 5, $row - 1, 5,
$prevpkg->{version}, $f_data );
$start_merge = 0;
}
$prevpkg = $curpkg;
$row++;
}
}
sub write_output_xml($) {
my @pkgs_list = values \%QSDKPKGS;
my $xml_list = { package => \@pkgs_list } ;
XMLout( $xml_list,
OutputFile => $_,
XMLDecl => 1,
RootName => 'release');
}
sub write_output() {
for ( @{ $OPTS{o} } ) {
if (/^.*\.xlsx$/) { write_output_xlsx($_); next; }
if (/^.*\.xml$/) { write_output_xml($_); next; }
print("$_: file format not recognized\n");
}
}
sub show_help() {
print <<EOF
$0 [options] config1 config2 config3 ...
Available Options:
-o filename Output file name (default: openwrt.xlsx)
EOF
}
sub show_help_and_exit($) {
print "Error: $_[0]\n" if defined $_[0];
show_help();
exit 1;
}
sub parse_command() {
while ( my $opt = shift @ARGV ) {
if ( $opt =~ /^-o$/ ) { push( @{ $OPTS{o} }, shift(@ARGV) ) }
elsif ( $opt =~ /^-.*$/ ) {
show_help_and_exit("\"$opt\" option not supported");
}
else { load_config($opt); }
}
if ( !defined( $OPTS{o} ) ) {
push( @{ $OPTS{o} }, "openwrt.xlsx" );
}
}
parse_command();
parse_package_metadata("tmp/.packageinfo");
xref_packages();
write_output();