b74119aed7
Change-Id: I8dbe60b85d0a330e3b2b5f54984b561fe9be05be
475 lines
15 KiB
Perl
Executable file
475 lines
15 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
|
|
if $running_under_some_shell;
|
|
#!/usr/bin/perl
|
|
|
|
use strict;
|
|
use File::Copy;
|
|
use File::Temp qw/ tempfile tempdir /;
|
|
|
|
# get libreoffice-build version from the given libreoffice-build sources
|
|
sub get_config_version($)
|
|
{
|
|
my ($lo_core_dir) = @_;
|
|
my $version;
|
|
|
|
open (CONFIGURE, "$lo_core_dir/configure.in") ||
|
|
die "can't open \"$lo_core_dir/configure.in\" for reading: $!\n";
|
|
|
|
while (my $line = <CONFIGURE>) {
|
|
chomp $line;
|
|
|
|
if ($line =~ /AC_INIT\s*\(\s*libreoffice-build\s*,\s*([\w\.]*)\)/) {
|
|
$version="$1";
|
|
}
|
|
}
|
|
close (CONFIGURE);
|
|
return $version;
|
|
}
|
|
|
|
# increment the version for a test build:
|
|
# + add 'a' if the version ended with a number
|
|
# + bump the letter otherwise
|
|
sub inc_test_version($)
|
|
{
|
|
my ($version) = @_;
|
|
|
|
my $lastchar = chop $version;
|
|
my $new_version;
|
|
|
|
if ($lastchar =~ /\d/) {
|
|
return "$version" . "$lastchar" . "a";
|
|
} elsif ($lastchar =~ /\w/) {
|
|
# select next letter alhabeticaly: a->b, b->c, ...
|
|
$lastchar =~ tr/0a-zA-Z/a-zA-Z0/;
|
|
return "$version" . "$lastchar";
|
|
} else {
|
|
die "Can't generate test version from \"$version$lastchar\n";
|
|
}
|
|
}
|
|
|
|
sub get_release_version($$$$)
|
|
{
|
|
my ($config_version, $state_config_version, $state_release_version, $inc_version) = @_;
|
|
my $release_version;
|
|
|
|
if (defined $state_config_version &&
|
|
defined $state_release_version &&
|
|
"$state_config_version" eq "$config_version") {
|
|
$release_version = "$state_release_version";
|
|
} else {
|
|
$release_version = "$config_version";
|
|
}
|
|
|
|
if ( defined $inc_version ) {
|
|
$release_version = inc_test_version($release_version);
|
|
}
|
|
|
|
return $release_version;
|
|
}
|
|
|
|
# copy files to temp dir; showing a progress; using a black list
|
|
sub copy_dir_filter_and_show_progress($$)
|
|
{
|
|
my ($source_dir, $target_dir) = @_;
|
|
|
|
print "Copying \"$source_dir\" -> \"$target_dir\"...";
|
|
# copy sources from git and show progress
|
|
system ("cd $source_dir && " .
|
|
"git archive --format=tar HEAD | " .
|
|
" tar -xf - -C $target_dir --checkpoint=500 --checkpoint-action=exec=\"echo -n .\"") &&
|
|
die "Error: copying failed: $!\n";
|
|
print "\n";
|
|
}
|
|
|
|
# copy the piece lo source directory into a tmp directory
|
|
# omit the .git subdirectories
|
|
sub copy_lo_piece_to_tempdir($$$)
|
|
{
|
|
my ($piece_dir, $piece, $piece_tarball_name) = @_;
|
|
my $tempdir = tempdir( 'libreoffice-XXXXXX', DIR => File::Spec->tmpdir );
|
|
|
|
mkdir "$tempdir/$piece_tarball_name" || die "Can't create directory \"$tempdir/$piece_tarball_name\": $!\n";
|
|
copy_dir_filter_and_show_progress("$piece_dir", "$tempdir/$piece_tarball_name");
|
|
|
|
return $tempdir;
|
|
}
|
|
|
|
sub generate_lo_piece_changelog($$$)
|
|
{
|
|
my ($lo_piece_clone, $lo_piece_release_dir, $piece) = @_;
|
|
print "Generating changelog for $piece...\n";
|
|
# print "1:$lo_piece_clone, 2:$lo_piece_release_dir, 3:$piece\n";
|
|
system ("cd $lo_piece_clone && " .
|
|
"git log --date=short --pretty='format:@%cd %an <%ae> [%H]%n%n%s%n%n%e%b' | " .
|
|
" sed -e 's|^\([^@]\)|\t\1|' -e 's|^@||' >$lo_piece_release_dir/ChangeLog" ) &&
|
|
die "Error: generating failed: $!\n";
|
|
}
|
|
|
|
sub run_autoreconf($$)
|
|
{
|
|
my ($dir, $piece) = @_;
|
|
|
|
print "Running autoreconf for $piece...\n";
|
|
system ("cd $dir && " .
|
|
"autoreconf -f -i && " .
|
|
"rm -rf autom4te.cache && " .
|
|
"cd - >/dev/null 2>&1") && die "Error: autoreconf failed: $!\n";
|
|
}
|
|
|
|
sub generate_sources_version_file($$)
|
|
{
|
|
my ($dir, $release_version) = @_;
|
|
|
|
open (VERFILE, ">$dir/sources.ver") || die "Can't open $dir/sources.ver: $!\n";
|
|
|
|
print VERFILE "lo_sources_ver=$release_version\n";
|
|
|
|
close VERFILE;
|
|
}
|
|
|
|
sub generate_tarball($$$)
|
|
{
|
|
my ($dir, $tarball, $tar_compress_option) = @_;
|
|
|
|
print "Creating $tarball...";
|
|
# generate the tarball in the current directory; avoid "./" prefix in the stored paths; show progress
|
|
system ("tar -c $tar_compress_option -f $tarball -C $dir --checkpoint=500 --checkpoint-action=exec=\"echo -n .\" --transform=\"s|^\./||\" .") &&
|
|
die "Error: releasing failed: $!\n";
|
|
print "\n";
|
|
}
|
|
|
|
sub generate_md5($)
|
|
{
|
|
my ($filename) = @_;
|
|
|
|
print "Generating MD5...\n";
|
|
system ("md5sum $filename >$filename.md5") &&
|
|
die "Error: releasing failed: $!\n";
|
|
}
|
|
|
|
sub default_releases_state_file($)
|
|
{
|
|
my ($lo_core_dir) = @_;
|
|
|
|
my $rootdir = $lo_core_dir;
|
|
$rootdir =~ s/^(.*?)\/?[^\/]+\/?$/$1/;
|
|
|
|
my $releases_state_file;
|
|
if ($rootdir) {
|
|
$releases_state_file = "$rootdir/.releases";
|
|
} else {
|
|
$releases_state_file = ".releases";
|
|
}
|
|
|
|
return "$releases_state_file";
|
|
}
|
|
|
|
sub load_releases_state($)
|
|
{
|
|
my ($releases_state_file) = @_;
|
|
|
|
my $state_config_version;
|
|
my $state_release_version;
|
|
|
|
if (open (STATE, "$releases_state_file")) {
|
|
|
|
while (my $line = <STATE>) {
|
|
chomp $line;
|
|
|
|
if ($line =~ /^\s*configure_version\s*=\s*(.*)$/) {
|
|
$state_config_version = "$1";
|
|
} elsif ($line =~ /^\s*released_version\s*=\s*(.*)$/) {
|
|
$state_release_version = "$1";
|
|
}
|
|
}
|
|
close (STATE);
|
|
}
|
|
|
|
return $state_config_version, $state_release_version;
|
|
}
|
|
|
|
sub save_releases_state($$$)
|
|
{
|
|
my ($releases_state_file, $config_version, $release_version) = @_;
|
|
|
|
open (STATE, '>', "$releases_state_file") ||
|
|
die "Can't open \"$releases_state_file\" for writing: $!\n";
|
|
|
|
print STATE "configure_version = $config_version\n";
|
|
print STATE "released_version = $release_version\n";
|
|
|
|
close (STATE);
|
|
}
|
|
|
|
sub remove_tempdir($)
|
|
{
|
|
my ($tempdir) = @_;
|
|
|
|
# print "Cleaning $tempdir...\n";
|
|
system ("rm -rf $tempdir") && die "Error: rm failed: $!\n";
|
|
}
|
|
|
|
sub check_if_file_exists($$)
|
|
{
|
|
my ($file, $force) = @_;
|
|
|
|
if (-e $file) {
|
|
if (defined $force) {
|
|
print "Warning: $file already exists and will be replaced!\n";
|
|
} else {
|
|
die "Error: $file alrady exists.\n".
|
|
" Use --force if you want to replace it.\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
sub check_if_already_released($$$$$$$)
|
|
{
|
|
my ($lo_core_tarball_name, $p_piece_tarball_name, $force, $bzip2, $xz, $pack_lo_core, $pack_lo_pieces) = @_;
|
|
|
|
check_if_file_exists("$lo_core_tarball_name.tar.bz2", $force) if ($pack_lo_core && defined $bzip2);
|
|
check_if_file_exists("$lo_core_tarball_name.tar.xz", $force) if ($pack_lo_core && defined $xz);
|
|
|
|
if ($pack_lo_pieces) {
|
|
foreach my $tarball_name ( values %{$p_piece_tarball_name} ) {
|
|
check_if_file_exists("$tarball_name.tar.bz2", $force) if (defined $bzip2);
|
|
check_if_file_exists("$tarball_name.tar.xz", $force) if (defined $xz);
|
|
}
|
|
}
|
|
}
|
|
|
|
sub prepare_piece_sources($$$$)
|
|
{
|
|
my ($piece_dir, $release_version, $piece, $piece_tarball_name) = @_;
|
|
|
|
# prepare sources
|
|
my $temp_dir = copy_lo_piece_to_tempdir($piece_dir, $piece, $piece_tarball_name);
|
|
generate_lo_piece_changelog($piece_dir, "$temp_dir/$piece_tarball_name", $piece);
|
|
run_autoreconf("$temp_dir/$piece_tarball_name", $piece) if ($piece eq 'core');
|
|
generate_sources_version_file("$temp_dir/$piece_tarball_name", $release_version) if ($piece eq 'core');
|
|
|
|
return $temp_dir;
|
|
}
|
|
|
|
sub pack_piece_sources($$$$)
|
|
{
|
|
my ($temp_dir, $md5, $tarball, $tar_compress_option) = @_;
|
|
|
|
generate_tarball($temp_dir, $tarball, $tar_compress_option);
|
|
generate_md5($tarball) if (defined $md5);
|
|
}
|
|
|
|
sub generate_piece_tarball($$$$$$$)
|
|
{
|
|
my ($piece_dir, $release_version, $piece, $md5, $bzip2, $xz, $piece_tarball_name) = @_;
|
|
|
|
my $temp_dir = prepare_piece_sources($piece_dir, $release_version, $piece, $piece_tarball_name);
|
|
pack_piece_sources($temp_dir, $md5, "$piece_tarball_name.tar.bz2", "--bzip2") if (defined $bzip2);
|
|
pack_piece_sources($temp_dir, $md5, "$piece_tarball_name.tar.xz", "--xz") if (defined $xz);
|
|
remove_tempdir($temp_dir);
|
|
}
|
|
|
|
|
|
sub generate_tarballs($$$$$$$$$$)
|
|
{
|
|
my ($source_dir, $release_version, $md5, $bzip2, $xz, $lo_core_tarball_name, $p_piece_tarball_name, $pack_lo_core, $pack_lo_pieces, $is_lo_core_dir) = @_;
|
|
|
|
if ($pack_lo_core) {
|
|
generate_piece_tarball($source_dir, $release_version, "core", $md5, $bzip2, $xz, $lo_core_tarball_name);
|
|
}
|
|
|
|
if ($pack_lo_pieces) {
|
|
my $piece_dir = $source_dir;
|
|
foreach my $piece ( keys %{$p_piece_tarball_name} ) {
|
|
print "\n--- Generating $piece ---\n";
|
|
$piece_dir = "$source_dir/clone/$piece" if ($is_lo_core_dir);
|
|
generate_piece_tarball($piece_dir, $release_version, $piece, $md5, $bzip2, $xz, $p_piece_tarball_name->{$piece});
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
sub usage()
|
|
{
|
|
print "This tool helps to pack the libreoffice-build and piece sources\n\n" .
|
|
|
|
"Usage:\n".
|
|
"\tlo-pack-sources [--help]\n" .
|
|
"\t [--force] [--md5] [--bzip2] [--xz]\n" .
|
|
"\t [--version][--set-version=<ver>] [--inc-version]\n" .
|
|
"\t [--no-lo-core] [--no-lo-pieces] [--piece=<piece>]\n" .
|
|
"\t [dir]\n\n" .
|
|
|
|
"Options:\n\n" .
|
|
"\t--help: print this help\n" .
|
|
"\t--force: replace an already existing release of the same version\n" .
|
|
"\t--md5: generate md5 sum for the final tarball\n" .
|
|
"\t--bzip2: generate tarballs compressed by bzip2\n" .
|
|
"\t--xz: generate tarballs compressed by xz (default)\n" .
|
|
"\t--version: just print version of the released package but do not\n" .
|
|
"\t\trelease it; the version is affected by the other options, e.g.\n" .
|
|
"\t\t--inc-version\n" .
|
|
"\t--set-version: force another version\n" .
|
|
"\t--inc-version: increment the latest version; there is a difference\n" .
|
|
"\t\tbetween test release (default) and final (not yet supported)\n" .
|
|
"\t--no-lo-core: do not pack the libreoffice-core tarball\n" .
|
|
"\t--no-lo-pieces: do not pack the extra LO piece sources\n" .
|
|
"\t--piece=<piece>: pack just a single piece, .e.g. \"help\",\n" .
|
|
"\tdir: path of the source directory, either libreoffice-build or piece\n";
|
|
}
|
|
|
|
|
|
my $ptf;
|
|
my $md5;
|
|
my $bzip2;
|
|
my $xz;
|
|
my $inc_version;
|
|
my $config_version;
|
|
my $set_version;
|
|
my $get_config_version;
|
|
my $release_version;
|
|
my $pack_lo_core=1;
|
|
my $pack_lo_pieces=1;
|
|
my $source_dir;
|
|
my $releases_state_file;
|
|
my $state_config_version;
|
|
my $state_release_version;
|
|
my $lo_core_tarball_name;
|
|
my $lo_core_tempdir;
|
|
my $force;
|
|
my $verbose=1;
|
|
my $is_lo_core_dir=0;
|
|
my @pieces=("binfilter", "dictionaries", "help", "translations");
|
|
my %piece_tarball_name;
|
|
|
|
###################
|
|
# Arguments parsing
|
|
###################
|
|
|
|
for my $arg (@ARGV) {
|
|
if ($arg eq '--help' || $arg eq '-h') {
|
|
usage;
|
|
exit 0;
|
|
} elsif ($arg eq '--force') {
|
|
$force=1;
|
|
} elsif ($arg eq '--md5') {
|
|
$md5=1;
|
|
} elsif ($arg eq '--bzip2') {
|
|
$bzip2=1;
|
|
} elsif ($arg eq '--xz') {
|
|
$xz=1;
|
|
} elsif ($arg eq '--version') {
|
|
$get_config_version=1;
|
|
$verbose = undef;
|
|
} elsif ($arg eq '--inc-version') {
|
|
$inc_version=1
|
|
} elsif ($arg =~ m/--set-version=(.*)/) {
|
|
$set_version="$1";
|
|
} elsif ($arg eq '--no-lo-core') {
|
|
$pack_lo_core=0;
|
|
} elsif ($arg eq '--no-lo-pieces') {
|
|
$pack_lo_pieces=0;
|
|
} elsif ($arg =~ m/--piece=(.*)/) {
|
|
# process just one piece and do not pack libreoffice-build
|
|
@pieces=();
|
|
push @pieces, "$1";
|
|
$pack_lo_core=0;
|
|
} elsif ($arg =~ /^-/ ) {
|
|
die "Error: unknown option: $arg\n";
|
|
} else {
|
|
if (! defined $source_dir) {
|
|
$source_dir = $arg;
|
|
} else {
|
|
die "Error: Too many arguments $arg\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
###################
|
|
# Initial checks
|
|
###################
|
|
|
|
unless ( defined $source_dir ) {
|
|
die "Error: undefined source directory, try --help\n";
|
|
}
|
|
|
|
unless ( -d "$source_dir" ) {
|
|
die "Error: is not a directory: $source_dir\n";
|
|
}
|
|
|
|
# check if it is a valid libreoffice-core directory
|
|
$is_lo_core_dir=1 if (-f "$source_dir/autogen.sh" && -f "$source_dir/config_host.mk.in");
|
|
|
|
# all tarballs are generated from the libreoffice-core directory
|
|
if (@pieces > 1 && $is_lo_core_dir == 0 ) {
|
|
die "Error: \"$source_dir\" is not a valid libreoffice-core directory\n";
|
|
}
|
|
|
|
# just a single piece tarball can be generated from piece directory; version must be explicitly set in this case
|
|
if (@pieces == 1 && $is_lo_core_dir == 0 && ! defined $set_version ) {
|
|
die "Error: version must be set using the --set-version=<version> option\n" unless (defined $set_version);
|
|
}
|
|
|
|
if (defined $set_version && defined $inc_version) {
|
|
die "Error: --set-version and --inc-version options can't be used together\n";
|
|
}
|
|
|
|
# default compression
|
|
$xz = 1 unless (defined $xz || defined $bzip2);
|
|
|
|
|
|
###################
|
|
# Main logic
|
|
###################
|
|
|
|
|
|
print "Source: $source_dir\n" if ($verbose);
|
|
|
|
if ($is_lo_core_dir) {
|
|
# detect some paths
|
|
$releases_state_file = default_releases_state_file($source_dir) unless (defined $releases_state_file);
|
|
|
|
# detect versions
|
|
$config_version = get_config_version($source_dir);
|
|
($state_config_version, $state_release_version) = load_releases_state($releases_state_file);
|
|
if (defined $set_version) {
|
|
$release_version = "$set_version";
|
|
} else {
|
|
$release_version = get_release_version($config_version, $state_config_version, $state_release_version, $inc_version);
|
|
}
|
|
} else {
|
|
# must be single piece release with predefined version
|
|
$release_version = "$set_version";
|
|
}
|
|
|
|
# define tarball names
|
|
$lo_core_tarball_name = "libreoffice-core-$release_version";
|
|
foreach my $piece (@pieces) {
|
|
if (-d "$source_dir/clone/$piece") {
|
|
$piece_tarball_name{$piece} = "libreoffice-$piece-$release_version";
|
|
} else {
|
|
print "Warning: $piece sources are not available -> skipping\n";
|
|
}
|
|
}
|
|
|
|
print "Default version : $config_version\n" if ($verbose && defined $config_version);
|
|
print "Last used version : $state_release_version\n" if ($verbose && defined $state_release_version);
|
|
print "New version : $release_version\n" if ($verbose);
|
|
|
|
# do the real job
|
|
if ( defined $get_config_version ) {
|
|
print "$release_version\n";
|
|
} else {
|
|
check_if_already_released($lo_core_tarball_name, \%piece_tarball_name, $force, $bzip2, $xz, $pack_lo_core, $pack_lo_pieces);
|
|
|
|
# give a chance to stop the process
|
|
print ("\nWaiting 3 seconds...\n");
|
|
sleep 3;
|
|
|
|
generate_tarballs($source_dir, $release_version, $md5, $bzip2, $xz, $lo_core_tarball_name, \%piece_tarball_name, $pack_lo_core, $pack_lo_pieces, $is_lo_core_dir);
|
|
|
|
if ( defined $releases_state_file ) {
|
|
save_releases_state($releases_state_file, $config_version, $release_version);
|
|
}
|
|
}
|