File firefox-mkextpkg of Package firefox-pkggen
#!/usr/bin/perl -w
use Cwd;
use strict;
my $apiurl = "https://services.addons.mozilla.org/en-US/firefox/api/1.3/";
# http://www.spdx.org/licenses/
my %licenses = (
"Mozilla Public License, version 1.1" => "MPL-1.1",
"GNU General Public License, version 2.0" => "GPL-2.0",
);
use IO::Socket::SSL;
# load IO:Socket:SSL before LWP::UserAgent so it uses that instead
# of NET::SSL.
# We prefer IO:Socket:SSL as it does the host name verification for
# us already.
IO::Socket::SSL::set_ctx_defaults(
SSL_verifycn_scheme => {
wildcards_in_cn => 'anywhere',
wildcards_in_alt => 'anywhere',
check_cn => 'when_only'
},
SSL_verify_mode => 1,
SSL_ca_file => undef,
SSL_ca_path => "/etc/ssl/certs",
);
use LWP::UserAgent;
use XML::Simple;
use Template;
use Getopt::Long;
use Data::Dumper;
my %options;
Getopt::Long::Configure("no_ignore_case");
GetOptions (
\%options,
"update",
"force",
"oldversion",
"check",
"debug",
) or die "invalid arguments\n";
my $ua = LWP::UserAgent->new();
$ua->timeout(20);
my $newsuffix = '';
my $oldversion;
my $pkgname;
my $specfile;
my $id = shift @ARGV || die "usage: $0 appid\n";
if (!-d $id) {
die "id must be numeric\n" unless ($id =~ /\d+/);
} else {
$pkgname = $id;
$id = undef;
if ($pkgname eq '.') {
$pkgname = getcwd;
$pkgname =~ s,.*/,,;
}
die "$pkgname already exists, use --update to update\n" unless ($options{'update'} || $options{'check'});
$specfile = "$pkgname.spec";
if (-d $pkgname) {
$specfile = "$pkgname/$specfile";
}
die "$!\n" unless open(I, '<', $specfile);
while(<I>) {
if (/^Version:\s*(.+)\n/) {
$oldversion = $1;
} elsif (/^URL:.*\/(\d+)\n/) {
$id = $1;
last;
}
}
close(I);
die "can't determine id for $pkgname\n" unless $id;
}
my $data;
if (@ARGV) {
$data = join('', <>);
} else {
my $req = HTTP::Request->new('GET' => $apiurl."addon/$id");
my $res = $ua->request($req);
die $res->status_line."\n" unless $res->is_success;
$data = $res->content;
}
my $xml = XML::Simple->new();
my $tree = $xml->XMLin($data);
my %variables;
print Dumper($tree) if $options{'debug'};
for my $tag (qw/name version summary description/) {
next unless exists $tree->{$tag};
if (!ref $tree->{$tag}) {
$variables{$tag} = $tree->{$tag}
} elsif(ref $tree->{$tag} eq 'HASH') {
$variables{$tag} = $tree->{$tag}->{'content'};
} else {
print STDERR "tag $tag not found\n";
}
}
if ($tree->{'license'} && $tree->{'license'}->{'name'}) {
my $license = $tree->{'license'}->{'name'};
$license = $licenses{$license} if exists $licenses{$license};
$variables{'license'} = $license;
}
print Dumper(\%variables) if $options{'debug'};
if ($options{'check'}) {
exit 1 unless $oldversion;
if ($variables{'version'} eq $oldversion) {
print "$oldversion up to date\n";
exit 0;
} else {
printf "new version %s available\n", $variables{'version'};
exit 1;
}
}
unless ($options{'check'}) {
if ($oldversion && $variables{'version'} eq $oldversion) {
print "$oldversion is up to date\n";
exit 0 unless $options{'force'};
}
}
# upstream summary is too verbose
$variables{'summary'} = sprintf("%s extension for Firefox", $variables{'name'});
unless ($pkgname) {
$pkgname = lc $variables{'name'};
$pkgname =~ s/[^a-zA-Z0-9]/_/g;
$pkgname =~ s/_+/_/g;
$pkgname =~ s/_+$//g;
$pkgname = sprintf("firefox-ext-%s", lc $pkgname);
$specfile = "$pkgname/$pkgname.spec";
}
$variables{'pkgname'} = $pkgname;
sub makearray
{
my $ref = shift;
return $ref if ref $ref eq 'ARRAY';
return [ $ref ];
}
my $source;
my $dlfile;
my $hash;
for my $i (@{makearray($tree->{'install'})}) {
next unless ($i->{'os'} || 'nomatch') eq 'ALL';
$source = $i->{'content'};
$hash = $i->{'hash'} if ($i->{'hash'});
}
if (!$source) {
print STDERR "no suitable source found\n";
$source = 'FIXME';
} else {
my $version = $variables{'version'};
$dlfile = $source;
$source =~ s/\?.*//;
$source =~ s/\Q$version\E/%{version}/;
$variables{'hash'} = $hash;
}
# https://wiki.mozilla.org/Update:Remora_API_Docs
$variables{'url'} = sprintf("https://addons.mozilla.org/en-US/addon/%d", $id);
$variables{'source'} = $source;
if (-e $specfile) {
# reuse license if existing
#!defined $variables{'license'} &&
if (open(I, '<', $specfile)) {
while(<I>) {
if (/^License:\s*(.+)\n/) {
print "using license $1 from spec file\n";
$variables{'license'} = $1;
last;
}
}
close I;
}
} elsif ($specfile =~ /\//) {
mkdir($pkgname) || die "mkdir: $!\n";
}
$variables{'license'} ||= 'FIXME';
open(O, '>', "$specfile$newsuffix") or die "open: $!\n";
my $spec = '';
my %tmplcfg;
my $tt = Template->new(\%tmplcfg) || die Template->error(), "\n";
$tt->process(\*DATA, \%variables, \*O) || die $tt->error(), "\n";
close O;
sub get_file($$)
{
my ($url, $dest) = @_;
print "downloading $dest\n";
my $res = $ua->mirror($url, $dest);
die $res->status_line."\n" unless $res->is_success || $res->code == 304;
}
if ($dlfile) {
my $dest = $dlfile;
$dest =~ s/.*\///;
$dest =~ s/\?.*//;
$dest = $pkgname."/".$dest if $specfile =~ /\//;
get_file($dlfile, $dest);
if (!$hash || $hash !~ /^(sha\d+):(.*)/) {
print "Warning: can't verify hash!\n";
} else {
use Digest::SHA;
my $sha = Digest::SHA->new($1);
$sha->addfile($dest);
my $digest = $sha->hexdigest;
if ($digest ne $2) {
print STDERR "ERROR: digest doesn't match! ($digest != $2)\n";
}
}
}
printf "%s\n", $variables{'url'};
unless ($options{'update'}) {
print "\nDon't forget to fix up the License tag!\n";
print "osc mkpac $pkgname\n";
}
print "cd $pkgname\n" if $specfile =~ /\//;
unless ($options{'update'}) {
print "vi $pkgname.spec\n";
print "osc vc -m \"new package version $variables{version}\"\n";
} else {
print "osc diff\n";
print "osc vc -m \"update to version $variables{version}\"\n";
}
print "osc addremove\n";
print "osc ci\n";
print "osc metafromspec\n";
__END__
Name: [% pkgname %]
Version: [% version %]
Release: 1
License: [% license %]
Summary: [% summary %]
Group: Productivity/Networking/Web/Browsers
URL: [% url %]
Source0: [% source %]
[% IF hash -%]
#Hash: [% hash %]
[% END -%]
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
Requires: firefox >= %{firefox_version}
BuildRequires: firefox-devel
BuildRequires: unzip
BuildRequires: fdupes
Buildarch: noarch
%description
[% description %]
%prep
%setup -qTcn %{name}-%{version}
%build
%install
%firefox_ext_install %SOURCE0
%fdupes "%{buildroot}%{firefox_extdir}"
%clean
rm -rf %{buildroot}
%files
%defattr(0644,root,root,0755)
%{firefox_extdir}
%changelog