Make ElementsDeck the default deck for Math first start
[LibreOffice.git] / bin / lo-pack-sources
blob8c795dc170c51db35685e60cb5a7b1c118b51181
1 #!/usr/bin/perl
2 eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
3 if $running_under_some_shell;
4 #!/usr/bin/perl
6 use strict;
7 use File::Copy;
8 use File::Temp qw/ tempfile tempdir /;
10 my %module_dirname = (
11 "core" => "",
12 "dictionaries" => "dictionaries",
13 "help" => "helpcontent2",
14 "translations" => "translations"
16 my $lo_topdir_name;
18 # get libreoffice-build version from the given libreoffice-build sources
19 sub get_config_version($)
21 my ($lo_core_dir) = @_;
22 my $version;
24 open (CONFIGURE, "$lo_core_dir/configure.ac") ||
25 die "can't open \"$lo_core_dir/configure.ac\" for reading: $!\n";
27 while (my $line = <CONFIGURE>) {
28 chomp $line;
30 if ($line =~ /AC_INIT\s*\(\s*libreoffice-build\s*,\s*([\w\.]*)\)/) {
31 $version="$1";
34 close (CONFIGURE);
35 return $version;
38 # increment the version for a test build:
39 # + add 'a' if the version ended with a number
40 # + bump the letter otherwise
41 sub inc_test_version($)
43 my ($version) = @_;
45 my $lastchar = chop $version;
46 my $new_version;
48 if ($lastchar =~ /\d/) {
49 return "$version" . "$lastchar" . "a";
50 } elsif ($lastchar =~ /\w/) {
51 # select next letter alphabetically: a->b, b->c, ...
52 $lastchar =~ tr/0a-zA-Z/a-zA-Z0/;
53 return "$version" . "$lastchar";
54 } else {
55 die "Can't generate test version from \"$version$lastchar\n";
59 sub get_release_version($$$$)
61 my ($config_version, $state_config_version, $state_release_version, $inc_version) = @_;
62 my $release_version;
64 if (defined $state_config_version &&
65 defined $state_release_version &&
66 "$state_config_version" eq "$config_version") {
67 $release_version = "$state_release_version";
68 } else {
69 $release_version = "$config_version";
72 if ( defined $inc_version ) {
73 $release_version = inc_test_version($release_version);
76 return $release_version;
79 # copy files to temp dir; showing a progress; using a black list
80 sub copy_dir_filter_and_show_progress($$)
82 my ($source_dir, $target_dir) = @_;
84 print "Copying \"$source_dir\" -> \"$target_dir\"...";
85 # copy sources from git and show progress
86 system ("cd $source_dir && " .
87 "git archive --format=tar HEAD | " .
88 " tar -xf - -C $target_dir ") &&
89 die "Error: copying failed: $!\n";
90 print "\n";
93 # copy files to temp dir; showing a progress; using a black list
94 sub remove_empty_submodules($)
96 my ($target_topdir) = @_;
98 foreach my $submodule (sort values %module_dirname) {
99 next unless ($submodule);
100 print "Removing empty submodule: $submodule...\n";
101 rmdir "$target_topdir/$submodule" || die "Error: Can't remove submodule directory: $target_topdir/$submodule";
105 # copy the source directory into a tmp directory
106 # omit the .git subdirectories
107 sub copy_lo_module_to_tempdir($$$)
109 my ($source_dir, $module, $lo_topdir_name) = @_;
110 my $tempdir = tempdir( 'libreoffice-XXXXXX', DIR => File::Spec->tmpdir );
112 mkdir "$tempdir/$lo_topdir_name" || die "Can't create directory \"$tempdir/$lo_topdir_name\": $!\n";
113 mkdir "$tempdir/$lo_topdir_name/$module_dirname{$module}" || die "Can't create directory \"$tempdir/$lo_topdir_name/$module_dirname{$module}\": $!\n" if ($module_dirname{$module});
115 copy_dir_filter_and_show_progress("$source_dir/$module_dirname{$module}", "$tempdir/$lo_topdir_name/$module_dirname{$module}");
116 remove_empty_submodules("$tempdir/$lo_topdir_name/") if ($module eq "core");
118 return $tempdir;
121 sub generate_lo_module_changelog($$$)
123 my ($source_dir, $lo_module_release_topdir, $module) = @_;
125 my $log_name = "ChangeLog";
126 $log_name .= "-$module_dirname{$module}" if ($module_dirname{$module});
127 print "Generating changelog for $module...\n";
128 system ("cd $source_dir/$module_dirname{$module} && " .
129 "git log --date=short --pretty='format:%cd %an <%ae> [%H]%n%n%w(0,8,8)%s%n%e%+b' " .
130 ">$lo_module_release_topdir/$log_name" ) &&
131 die "Error: generating failed: $!\n";
134 sub run_autogen($$)
136 my ($dir, $module) = @_;
138 print "Running autogen for $module...\n";
139 system ("cd $dir && " .
140 "NOCONFIGURE=1 ./autogen.sh && " .
141 "rm -rf autom4te.cache && " .
142 "cd - >/dev/null 2>&1") && die "Error: autogen failed: $!\n";
145 sub generate_sources_version_file($$)
147 my ($dir, $release_version) = @_;
149 open (VERFILE, ">$dir/sources.ver") || die "Can't open $dir/sources.ver: $!\n";
151 print VERFILE "lo_sources_ver=$release_version\n";
153 close VERFILE;
156 sub generate_tarball($$$)
158 my ($dir, $tarball, $tar_compress_option) = @_;
160 print "Creating $tarball...";
161 # generate the tarball in the current directory; avoid "./" prefix in the stored paths; show progress
162 system ("tar -c $tar_compress_option -f $tarball -C $dir $lo_topdir_name") &&
163 die "Error: releasing failed: $!\n";
164 print "\n";
167 sub generate_md5($)
169 my ($filename) = @_;
171 print "Generating MD5...\n";
172 system ("md5sum $filename >$filename.md5") &&
173 die "Error: releasing failed: $!\n";
176 sub default_releases_state_file($)
178 my ($lo_core_dir) = @_;
180 my $rootdir = $lo_core_dir;
181 $rootdir =~ s/^(.*?)\/?[^\/]+\/?$/$1/;
183 my $releases_state_file;
184 if ($rootdir) {
185 $releases_state_file = "$rootdir/.releases";
186 } else {
187 $releases_state_file = ".releases";
190 return "$releases_state_file";
193 sub load_releases_state($)
195 my ($releases_state_file) = @_;
197 my $state_config_version;
198 my $state_release_version;
200 if (open (STATE, "$releases_state_file")) {
202 while (my $line = <STATE>) {
203 chomp $line;
205 if ($line =~ /^\s*configure_version\s*=\s*(.*)$/) {
206 $state_config_version = "$1";
207 } elsif ($line =~ /^\s*released_version\s*=\s*(.*)$/) {
208 $state_release_version = "$1";
211 close (STATE);
214 return $state_config_version, $state_release_version;
217 sub save_releases_state($$$)
219 my ($releases_state_file, $config_version, $release_version) = @_;
221 open (STATE, '>', "$releases_state_file") ||
222 die "Can't open \"$releases_state_file\" for writing: $!\n";
224 print STATE "configure_version = $config_version\n";
225 print STATE "released_version = $release_version\n";
227 close (STATE);
230 sub remove_tempdir($)
232 my ($tempdir) = @_;
234 # print "Cleaning $tempdir...\n";
235 system ("rm -rf $tempdir") && die "Error: rm failed: $!\n";
238 sub check_if_file_exists($$)
240 my ($file, $force) = @_;
242 if (-e $file) {
243 if (defined $force) {
244 print "Warning: $file already exists and will be replaced!\n";
245 } else {
246 die "Error: $file already exists.\n".
247 " Use --force if you want to replace it.\n";
252 sub check_if_already_released($$$$$$)
254 my ($p_module_tarball_name, $force, $bzip2, $xz, $pack_lo_core, $pack_lo_modules) = @_;
256 foreach my $tarball_name ( sort values %{$p_module_tarball_name} ) {
257 check_if_file_exists("$tarball_name.tar.bz2", $force) if (defined $bzip2);
258 check_if_file_exists("$tarball_name.tar.xz", $force) if (defined $xz);
262 sub prepare_module_sources($$$$)
264 my ($source_dir, $release_version, $module, $lo_topdir_name) = @_;
266 # prepare sources
267 my $temp_dir = copy_lo_module_to_tempdir($source_dir, $module, $lo_topdir_name);
268 generate_lo_module_changelog($source_dir, "$temp_dir/$lo_topdir_name", $module);
269 run_autogen("$temp_dir/$lo_topdir_name", $module) if ($module eq 'core');
270 generate_sources_version_file("$temp_dir/$lo_topdir_name", $release_version) if ($module eq 'core');
272 return $temp_dir;
275 sub pack_module_sources($$$$)
277 my ($temp_dir, $md5, $tarball, $tar_compress_option) = @_;
279 generate_tarball($temp_dir, $tarball, $tar_compress_option);
280 generate_md5($tarball) if (defined $md5);
283 sub generate_module_tarball($$$$$$$$)
285 my ($source_dir, $release_version, $module, $md5, $bzip2, $xz, $lo_topdir_name, $module_tarball_name) = @_;
287 my $temp_dir = prepare_module_sources($source_dir, $release_version, $module, $lo_topdir_name);
288 pack_module_sources($temp_dir, $md5, "$module_tarball_name.tar.bz2", "--bzip2") if (defined $bzip2);
289 pack_module_sources($temp_dir, $md5, "$module_tarball_name.tar.xz", "--xz") if (defined $xz);
290 remove_tempdir($temp_dir);
294 sub generate_tarballs($$$$$$$$$)
296 my ($source_dir, $release_version, $md5, $bzip2, $xz, $lo_topdir_name, $p_module_tarball_name, $pack_lo_core, $pack_lo_modules) = @_;
298 foreach my $module (sort keys %{$p_module_tarball_name} ) {
299 print "\n--- Generating $module ---\n";
300 generate_module_tarball($source_dir, $release_version, $module, $md5, $bzip2, $xz, $lo_topdir_name, $p_module_tarball_name->{$module});
305 sub usage()
307 print "This tool helps to pack the libreoffice-build and module sources\n\n" .
309 "Usage:\n".
310 "\tlo-pack-sources [--help]\n" .
311 "\t [--force] [--md5] [--bzip2] [--xz]\n" .
312 "\t [--version][--set-version=<ver>] [--inc-version]\n" .
313 "\t [--no-submodule] [--module=<module>]\n" .
314 "\t [dir]\n\n" .
316 "Options:\n\n" .
317 "\t--help: print this help\n" .
318 "\t--force: replace an already existing release of the same version\n" .
319 "\t--md5: generate md5 sum for the final tarball\n" .
320 "\t--bzip2: generate tarballs compressed by bzip2\n" .
321 "\t--xz: generate tarballs compressed by xz (default)\n" .
322 "\t--version: just print version of the released package but do not\n" .
323 "\t\trelease it; the version is affected by the other options, e.g.\n" .
324 "\t\t--inc-version\n" .
325 "\t--set-version: force another version\n" .
326 "\t--inc-version: increment the latest version; there is a difference\n" .
327 "\t\tbetween test release (default) and final (not yet supported)\n" .
328 "\t--no-submodule: do not pack sources from git submodules\n" .
329 "\t--module=<module>: pack just a single module, use \"core\"\n" .
330 "\t\tfor the main git repo,\n" .
331 "\tdir: path of the source directory, either libreoffice-build or module\n";
335 my $module;
336 my $ptf;
337 my $md5;
338 my $bzip2;
339 my $xz;
340 my $inc_version;
341 my $config_version;
342 my $set_version;
343 my $get_config_version;
344 my $release_version;
345 my $pack_lo_core=1;
346 my $pack_lo_modules=1;
347 my $source_dir;
348 my $releases_state_file;
349 my $state_config_version;
350 my $state_release_version;
351 my $lo_core_tempdir;
352 my $force;
353 my $verbose=1;
354 my %module_tarball_name;
356 ###################
357 # Arguments parsing
358 ###################
360 for my $arg (@ARGV) {
361 if ($arg eq '--help' || $arg eq '-h') {
362 usage;
363 exit 0;
364 } elsif ($arg eq '--force') {
365 $force=1;
366 } elsif ($arg eq '--md5') {
367 $md5=1;
368 } elsif ($arg eq '--bzip2') {
369 $bzip2=1;
370 } elsif ($arg eq '--xz') {
371 $xz=1;
372 } elsif ($arg eq '--version') {
373 $get_config_version=1;
374 $verbose = undef;
375 } elsif ($arg eq '--inc-version') {
376 $inc_version=1
377 } elsif ($arg =~ m/--set-version=(.*)/) {
378 $set_version="$1";
379 } elsif ($arg eq '--no-submodule') {
380 $module = "core";
381 } elsif ($arg =~ m/--module=(.*)/) {
382 # process just one module and do not pack libreoffice-build
383 die("Error: unknown module: $1") unless (defined $module_dirname{$1});
384 $module = $1;
385 } elsif ($arg =~ /^-/ ) {
386 die "Error: unknown option: $arg\n";
387 } else {
388 if (! defined $source_dir) {
389 $source_dir = $arg;
390 } else {
391 die "Error: Too many arguments $arg\n";
396 # ugly hack; we want only one module
397 if ($module) {
398 my $name = $module_dirname{$module};
399 %module_dirname = ();
400 $module_dirname{$module} = $name;
403 ###################
404 # Initial checks
405 ###################
407 unless ( defined $source_dir ) {
408 die "Error: undefined source directory, try --help\n";
411 unless ( -d "$source_dir" ) {
412 die "Error: is not a directory: $source_dir\n";
415 # check if it is a valid libreoffice-core directory
416 unless (-f "$source_dir/autogen.sh" && -f "$source_dir/config_host.mk.in") {
417 die "Error: \"$source_dir\" is not a valid libreoffice-core directory\n";
420 if (defined $set_version && defined $inc_version) {
421 die "Error: --set-version and --inc-version options can't be used together\n";
424 # default compression
425 $xz = 1 unless (defined $xz || defined $bzip2);
428 ###################
429 # Main logic
430 ###################
433 print "Source: $source_dir\n" if ($verbose);
435 # detect some paths
436 $releases_state_file = default_releases_state_file($source_dir) unless (defined $releases_state_file);
438 # detect versions
439 $config_version = get_config_version($source_dir);
440 ($state_config_version, $state_release_version) = load_releases_state($releases_state_file);
441 if (defined $set_version) {
442 $release_version = "$set_version";
443 } else {
444 $release_version = get_release_version($config_version, $state_config_version, $state_release_version, $inc_version);
447 # define tarball names
448 print "Detected module:\n";
449 foreach my $module (sort keys %module_dirname) {
450 if (-e "$source_dir/$module_dirname{$module}/.git") {
451 print " $module\n";
452 if ($module eq "core") {
453 $module_tarball_name{$module} = "libreoffice-$release_version";
454 } else {
455 $module_tarball_name{$module} = "libreoffice-$module-$release_version";
457 } else {
458 print "did not found: $source_dir/$module_dirname{$module}/.git\n";
459 print "Warning: $module sources are not available -> skipping\n";
463 # top directory inside the source tarballs
464 $lo_topdir_name = "libreoffice-$release_version";
466 print "Default version : $config_version\n" if ($verbose && defined $config_version);
467 print "Last used version : $state_release_version\n" if ($verbose && defined $state_release_version);
468 print "New version : $release_version\n" if ($verbose);
470 # do the real job
471 if ( defined $get_config_version ) {
472 print "$release_version\n";
473 } else {
474 check_if_already_released(\%module_tarball_name, $force, $bzip2, $xz, $pack_lo_core, $pack_lo_modules);
476 # give a chance to stop the process
477 print ("\nWaiting 3 seconds...\n");
478 sleep 3;
480 generate_tarballs($source_dir, $release_version, $md5, $bzip2, $xz, $lo_topdir_name, \%module_tarball_name, $pack_lo_core, $pack_lo_modules);
482 if ( defined $releases_state_file ) {
483 save_releases_state($releases_state_file, $config_version, $release_version);