1*c667dd47SPedro Giffuni#!/usr/bin/env perl 2f219747dSAndre Fischer#************************************************************** 3f219747dSAndre Fischer# 4f219747dSAndre Fischer# Licensed to the Apache Software Foundation (ASF) under one 5f219747dSAndre Fischer# or more contributor license agreements. See the NOTICE file 6f219747dSAndre Fischer# distributed with this work for additional information 7f219747dSAndre Fischer# regarding copyright ownership. The ASF licenses this file 8f219747dSAndre Fischer# to you under the Apache License, Version 2.0 (the 9f219747dSAndre Fischer# "License"); you may not use this file except in compliance 10f219747dSAndre Fischer# with the License. You may obtain a copy of the License at 11f219747dSAndre Fischer# 12f219747dSAndre Fischer# http://www.apache.org/licenses/LICENSE-2.0 13f219747dSAndre Fischer# 14f219747dSAndre Fischer# Unless required by applicable law or agreed to in writing, 15f219747dSAndre Fischer# software distributed under the License is distributed on an 16f219747dSAndre Fischer# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17f219747dSAndre Fischer# KIND, either express or implied. See the License for the 18f219747dSAndre Fischer# specific language governing permissions and limitations 19f219747dSAndre Fischer# under the License. 20f219747dSAndre Fischer# 21f219747dSAndre Fischer#************************************************************** 22f219747dSAndre Fischer 23f219747dSAndre Fischeruse strict; 241108b05eSAndre Fischeruse warnings; 25f219747dSAndre Fischeruse XML::LibXML; 26f219747dSAndre Fischeruse open OUT => ":utf8"; 27f219747dSAndre Fischeruse LWP::Simple; 28f219747dSAndre Fischeruse Digest; 29f219747dSAndre Fischeruse Digest::MD5; 30f219747dSAndre Fischeruse Digest::SHA; 319dd622cdSAndre Fischeruse File::Temp; 329dd622cdSAndre Fischeruse File::Path; 33f219747dSAndre Fischer 34f219747dSAndre Fischeruse Carp::always; 35f219747dSAndre Fischer 36f219747dSAndre Fischer=head1 NAME 37f219747dSAndre Fischer 38f219747dSAndre Fischer build_release.pl - Tool for batch release builds and uploads and the creation of wiki pages that list install sets. 39f219747dSAndre Fischer 40f219747dSAndre Fischer=head1 SYNOPSIS 41f219747dSAndre Fischer 42f219747dSAndre Fischer build_release.pl <command> {option} <release-description.xml> 43f219747dSAndre Fischer 44f219747dSAndre Fischer comands: 45f219747dSAndre Fischer build builds all install sets as requested by the XML file and supported by the platform. 469dd622cdSAndre Fischer build-missing 479dd622cdSAndre Fischer build only those install sets that have not been built earlier. 48f219747dSAndre Fischer upload upload install sets to a local or remote (via ssh with public/private key) 49f219747dSAndre Fischer directory structure. Uploads install sets that where build on other platforms. 50f219747dSAndre Fischer wiki create a wiki (MediaWiki syntax) snippet that references all install sets at the upload 51f219747dSAndre Fischer location. Includes install sets that where built and/or uploaded from other 52f219747dSAndre Fischer platforms and machines. 53f219747dSAndre Fischer options: 54f219747dSAndre Fischer -j <count> maximum number of build processes 55f219747dSAndre Fischer -k keep going if there are recoverable errors 56f219747dSAndre Fischer -u <path> upload destination 57f219747dSAndre Fischer -l check links on wiki page, write broken links as plain text 58f219747dSAndre Fischer -ld check links on wiki page, mark broken links 59f219747dSAndre Fischer -o <filename> filename of the output (wiki: wiki page, build: makefile) 609dd622cdSAndre Fischer -n <number> maximal number of upload tries, defaults to 5. 619dd622cdSAndre Fischer -d dry-run 62f219747dSAndre Fischer 639dd622cdSAndre Fischer Typical calls are: 649dd622cdSAndre Fischer build_release.pl build -j4 instsetoo_native/util/aoo-410-release.xml 659dd622cdSAndre Fischer for building the installation sets, language packs and patches for the 4.1 release. 669dd622cdSAndre Fischer 679dd622cdSAndre Fischer build_release.pl upload -u me@server:path -n 3 instsetoo_native/util/aoo-410-release.xml 689dd622cdSAndre Fischer to upload the previously built installation sets etc. 699dd622cdSAndre Fischer 709dd622cdSAndre Fischer build_release.pl wiki -o /tmp/wiki.txt instsetoo_native/util/aoo-410-release.xml 719dd622cdSAndre Fischer to create an updated wiki page with installation sets etc built at several 729dd622cdSAndre Fischer places and uploaded to several locations. 739dd622cdSAndre Fischer 749dd622cdSAndre Fischer 75f219747dSAndre Fischer=head1 XML file format 76f219747dSAndre Fischer 779dd622cdSAndre FischerThe release description could look like this: 789dd622cdSAndre Fischer 79f219747dSAndre Fischer<release 80f219747dSAndre Fischer name="snapshot" 81f219747dSAndre Fischer version="4.1.0"> 82f219747dSAndre Fischer 83f219747dSAndre Fischer <language 84f219747dSAndre Fischer id="ast" # As specified by 'configure --with-lang' 85f219747dSAndre Fischer english-name="Asturian" 86f219747dSAndre Fischer local-name="Asturianu" 87f219747dSAndre Fischer /> 88f219747dSAndre Fischer ... more languages 89f219747dSAndre Fischer 90f219747dSAndre Fischer <platform 91f219747dSAndre Fischer id="wntmsci12.pro" 92f219747dSAndre Fischer display-name="Windows" 93f219747dSAndre Fischer archive-platform="Win_x86" 94f219747dSAndre Fischer word-size="32" 959dd622cdSAndre Fischer package-types="msi" 969dd622cdSAndre Fischer extension="exe" 97f219747dSAndre Fischer /> 98f219747dSAndre Fischer ... more platforms 99f219747dSAndre Fischer 1009dd622cdSAndre Fischer <download 1019dd622cdSAndre Fischer platform-id="wntmsci12.pro" 1029dd622cdSAndre Fischer base-url="http://people.apache.org/~somebody/developer-snapshots/snapshot/win32" 1039dd622cdSAndre Fischer /> 104f219747dSAndre Fischer 105f219747dSAndre Fischer <package 1069dd622cdSAndre Fischer id="openoffice" 1079dd622cdSAndre Fischer target="openoffice" 108f219747dSAndre Fischer display-name="Full Install" 1099dd622cdSAndre Fischer archive-name="Apache_OpenOffice_%V_%P_install%T_%L.%E" 1109dd622cdSAndre Fischer /> 1119dd622cdSAndre Fischer 1129dd622cdSAndre Fischer <build 1139dd622cdSAndre Fischer package-id="openoffice" 1149dd622cdSAndre Fischer platform-list="all" 1159dd622cdSAndre Fischer language-list="all" 1169dd622cdSAndre Fischer /> 1179dd622cdSAndre Fischer ... more build entries 1189dd622cdSAndre Fischer 1199dd622cdSAndre Fischer <wiki> 1209dd622cdSAndre Fischer <package-ref 1219dd622cdSAndre Fischer package-id="openoffice" 122f219747dSAndre Fischer language-list="all" 123f219747dSAndre Fischer platform-list="all" 124f219747dSAndre Fischer table="main" 125f219747dSAndre Fischer /> 126f219747dSAndre Fischer ... more packages 127f219747dSAndre Fischer </wiki> 128f219747dSAndre Fischer 129f219747dSAndre Fischer</release> 1309dd622cdSAndre Fischer 1319dd622cdSAndre FischerA single <release> tag contains any number of 1329dd622cdSAndre Fischer 1339dd622cdSAndre Fischer<language> id 1349dd622cdSAndre Fischer The language id used internally by the build process, eg de, en-US 1359dd622cdSAndre Fischer english-name 1369dd622cdSAndre Fischer The english name of the language, eg german 1379dd622cdSAndre Fischer local-name 1389dd622cdSAndre Fischer The language name in that language, eg Deutsch 1399dd622cdSAndre Fischer 1409dd622cdSAndre Fischer Each listed language is expected to have been passed to configure via --with-lang 1419dd622cdSAndre Fischer The set of languages defines for which languages to 1429dd622cdSAndre Fischer build installation sets, language packs etc. (build command) 1439dd622cdSAndre Fischer upload installation sets, etc (upload command) 1449dd622cdSAndre Fischer add rows in the wiki page (wiki command) 1459dd622cdSAndre Fischer 1469dd622cdSAndre Fischer<platform> id 1479dd622cdSAndre Fischer The platform id that is used internally by the build process, eg wntmsci12.pro 1489dd622cdSAndre Fischer Note that <p>.pro and <p> are treated as two different platforms. 1499dd622cdSAndre Fischer display-name 1509dd622cdSAndre Fischer Name which is printed in the wiki table. 1519dd622cdSAndre Fischer archive-platform 1529dd622cdSAndre Fischer Platform name as used in the name of the installation set, eg Win_x86 1539dd622cdSAndre Fischer word-size 1549dd622cdSAndre Fischer Bit size of the installation sets, etc, typically either 32 or 64 1559dd622cdSAndre Fischer package-types 1569dd622cdSAndre Fischer Semicolon separated list of package types, eg "msi" or "deb;rpm" 1579dd622cdSAndre Fischer add-package-type-to-archive-name 1589dd622cdSAndre Fischer For deb and rpm archives it is necessary to add the package type to the archive name. 1599dd622cdSAndre Fischer extension 1609dd622cdSAndre Fischer Extension of the archive name, eg "exe" or "tar.gz" 1619dd622cdSAndre Fischer 1629dd622cdSAndre Fischer For the build command only those <platform> elements are used that match the platform on which this 1639dd622cdSAndre Fischer script is run. 1649dd622cdSAndre Fischer 1659dd622cdSAndre Fischer<download> 1669dd622cdSAndre Fischer platform-id 1679dd622cdSAndre Fischer Reference to one of the <platform> elements and has to match the id attribute of that platform. 1689dd622cdSAndre Fischer base-url 1699dd622cdSAndre Fischer URL head to which the name of the downloadable installation set etc. is appended. 1709dd622cdSAndre Fischer Eg. http://people.apache.org/~somebody/developer-snapshots/snapshot/win32 1719dd622cdSAndre Fischer 1729dd622cdSAndre Fischer Defines one download source that is referenced in the wiki page. Multiple <download> elements 1739dd622cdSAndre Fischer per platform are possible. Earlier entires are preferred over later ones. 1749dd622cdSAndre Fischer 1759dd622cdSAndre Fischer<package> 1769dd622cdSAndre Fischer id 1779dd622cdSAndre Fischer Internal name that is used to reference the package. 1789dd622cdSAndre Fischer target 1799dd622cdSAndre Fischer Target name recognized by instsetoo_native/util/makefile.mk, eg openoffice or oolanguagepack. 1809dd622cdSAndre Fischer display-name 1819dd622cdSAndre Fischer Name of the package that is shown in the wiki page, eg "Full Install" or "Langpack". 1829dd622cdSAndre Fischer archive-name 1839dd622cdSAndre Fischer Template of the archive name. 1849dd622cdSAndre Fischer %V version 1859dd622cdSAndre Fischer %P archive package name 1869dd622cdSAndre Fischer %T package type 1879dd622cdSAndre Fischer %L language 1889dd622cdSAndre Fischer %E extension. 1899dd622cdSAndre Fischer 1909dd622cdSAndre Fischer Defines a downloadable and distributable package, eg openoffice for the binary OpenOffice installation set. 191f219747dSAndre Fischer 1929dd622cdSAndre Fischer<build> target 1939dd622cdSAndre Fischer platform-list 1949dd622cdSAndre Fischer Semicolon separated list of platforms for which to build the target. 1959dd622cdSAndre Fischer Ignores all platforms that don't match the platform on which this script is executed. 1969dd622cdSAndre Fischer The special value 'all' is a shortcut for all platforms listed by <platform> elements. 1979dd622cdSAndre Fischer language-list 1989dd622cdSAndre Fischer Semicolon separated list of languages for which the build the target. 1999dd622cdSAndre Fischer The special value 'all' is a shortcut for all languages listed by <language> elements. 2009dd622cdSAndre Fischer 2019dd622cdSAndre Fischer Defines the sets of targets, plaforms and languages which are to be built. 2029dd622cdSAndre Fischer 2039dd622cdSAndre Fischer<wiki> 2049dd622cdSAndre Fischer <package-ref> 2059dd622cdSAndre Fischer package-id 2069dd622cdSAndre Fischer The id of the referenced package. 2079dd622cdSAndre Fischer platform-list 2089dd622cdSAndre Fischer See <build> tag for explanation. 2099dd622cdSAndre Fischer language-list 2109dd622cdSAndre Fischer See <build> tag for explanation. 2119dd622cdSAndre Fischer table 2129dd622cdSAndre Fischer Specifies the wiki table into which to add the package lines. Can be "main" or "secondary". 2139dd622cdSAndre Fischer 214f219747dSAndre Fischer=cut 215f219747dSAndre Fischer 216f219747dSAndre Fischer 217f219747dSAndre Fischer 218f219747dSAndre Fischermy %EnUSBasedLanguages = ( 219f219747dSAndre Fischer 'ast' => 1 220f219747dSAndre Fischer ); 221f219747dSAndre Fischer 222f219747dSAndre Fischer 2231108b05eSAndre Fischersub ProcessCommandline (@); 2241108b05eSAndre Fischersub PrintUsageAndExit (); 2251108b05eSAndre Fischersub Trim ($); 2261108b05eSAndre Fischersub ReadReleaseDescription ($$); 2271108b05eSAndre Fischersub ProcessBuildDescription ($$$); 2281108b05eSAndre Fischersub ProcessPlatformDescription ($$); 2291108b05eSAndre Fischersub ProcessDownloadDescription ($$); 2301108b05eSAndre Fischersub ProcessPackageDescription ($$); 2311108b05eSAndre Fischersub ProcessWikiPackageDescription ($$$); 2321108b05eSAndre Fischersub ProcessLanguageDescription ($$); 2331108b05eSAndre Fischersub PostprocessLanguageList ($$); 2341108b05eSAndre Fischersub PostprocessPlatformList ($$); 2351108b05eSAndre Fischersub CheckLanguageSet ($@); 2361108b05eSAndre Fischersub WriteMakefile ($$); 2371108b05eSAndre Fischersub Upload ($$); 2381108b05eSAndre Fischersub PrepareUploadArea ($@); 2391108b05eSAndre Fischersub UploadFilesViaRsync ($$@); 2401108b05eSAndre Fischersub CollectDownloadSets ($); 2411108b05eSAndre Fischersub ProvideChecksums ($@); 2421108b05eSAndre Fischersub IsOlderThan ($$); 2431108b05eSAndre Fischersub GetInstallationPackageName ($$$$); 2441108b05eSAndre Fischersub ResolveTemplate ($$$$$); 2451108b05eSAndre Fischersub GetCurrentPlatformDescriptor ($); 2461108b05eSAndre Fischersub Wiki ($$); 2471108b05eSAndre Fischersub GetTableList ($); 2481108b05eSAndre Fischersub GetPackagesForTable ($$); 2491108b05eSAndre Fischersub GetLanguagesForTable ($@); 2501108b05eSAndre Fischersub GetPlatformsForTable ($@); 2511108b05eSAndre Fischersub WriteDownloadLinks ($$$$$$$); 2521108b05eSAndre Fischersub FindDownload ($$$$$); 2531108b05eSAndre Fischersub CreateLink ($$$); 2541108b05eSAndre Fischersub CheckLink ($); 2551108b05eSAndre Fischersub SignFile ($$); 256f219747dSAndre Fischer 257f219747dSAndre Fischersub ProcessCommandline (@) 258f219747dSAndre Fischer{ 259f219747dSAndre Fischer my @arguments = @_; 260f219747dSAndre Fischer 261f219747dSAndre Fischer my $command = undef; 262f219747dSAndre Fischer my $description_filename = undef; 263f219747dSAndre Fischer my $max_process_count = 1; 264f219747dSAndre Fischer my $keep_going = 0; 265f219747dSAndre Fischer my $upload_destination = undef; 266f219747dSAndre Fischer my $check_links = 0; 267f219747dSAndre Fischer my $mark_broken_links = 0; 268f219747dSAndre Fischer my $output_filename = undef; 2699dd622cdSAndre Fischer my $max_upload_count = 5; 2709dd622cdSAndre Fischer my $build_only_missing = 0; 2719dd622cdSAndre Fischer my $dry_run = 0; 272f219747dSAndre Fischer 273f219747dSAndre Fischer my $error = 0; 274f219747dSAndre Fischer while (scalar @arguments > 0) 275f219747dSAndre Fischer { 276f219747dSAndre Fischer my $argument = shift @arguments; 277f219747dSAndre Fischer if ($argument =~ /^-/) 278f219747dSAndre Fischer { 279f219747dSAndre Fischer if ($argument eq "-j") 280f219747dSAndre Fischer { 281f219747dSAndre Fischer $max_process_count = shift @arguments; 282f219747dSAndre Fischer } 283f219747dSAndre Fischer elsif ($argument eq "-u") 284f219747dSAndre Fischer { 285f219747dSAndre Fischer $upload_destination = shift @arguments; 286f219747dSAndre Fischer $upload_destination =~ s/(\\|\/)$//; 287f219747dSAndre Fischer } 288f219747dSAndre Fischer elsif ($argument eq "-k") 289f219747dSAndre Fischer { 290f219747dSAndre Fischer $keep_going = 1; 291f219747dSAndre Fischer } 292f219747dSAndre Fischer elsif ($argument eq "-l") 293f219747dSAndre Fischer { 294f219747dSAndre Fischer $check_links = 1; 295f219747dSAndre Fischer } 296f219747dSAndre Fischer elsif ($argument eq "-ld") 297f219747dSAndre Fischer { 298f219747dSAndre Fischer $check_links = 1; 299f219747dSAndre Fischer $mark_broken_links = 1; 300f219747dSAndre Fischer } 301f219747dSAndre Fischer elsif ($argument eq "-o") 302f219747dSAndre Fischer { 303f219747dSAndre Fischer $output_filename = shift @arguments; 304f219747dSAndre Fischer } 3059dd622cdSAndre Fischer elsif ($argument eq "-n") 3069dd622cdSAndre Fischer { 3079dd622cdSAndre Fischer $max_upload_count = shift @arguments; 3089dd622cdSAndre Fischer } 3099dd622cdSAndre Fischer elsif ($argument eq "-d") 3109dd622cdSAndre Fischer { 3119dd622cdSAndre Fischer $dry_run = 1; 3129dd622cdSAndre Fischer } 313f219747dSAndre Fischer else 314f219747dSAndre Fischer { 315f219747dSAndre Fischer printf STDERR "unknown option $argument %s\n", $argument; 316f219747dSAndre Fischer $error = 1; 317f219747dSAndre Fischer } 318f219747dSAndre Fischer } 319f219747dSAndre Fischer elsif ( ! defined $command) 320f219747dSAndre Fischer { 321f219747dSAndre Fischer $command = $argument; 3221108b05eSAndre Fischer if ($command eq "build-missing") 3231108b05eSAndre Fischer { 3241108b05eSAndre Fischer $command = "build"; 3251108b05eSAndre Fischer $build_only_missing = 1; 3261108b05eSAndre Fischer } 3279dd622cdSAndre Fischer elsif ($command !~ /^(build|build-missing|upload|wiki)$/) 328f219747dSAndre Fischer { 329f219747dSAndre Fischer printf STDERR "unknown command '%s'\n", $command; 330f219747dSAndre Fischer $error = 1; 331f219747dSAndre Fischer } 332f219747dSAndre Fischer } 333f219747dSAndre Fischer else 334f219747dSAndre Fischer { 335f219747dSAndre Fischer $description_filename = $argument; 336f219747dSAndre Fischer if ( ! -f $description_filename) 337f219747dSAndre Fischer { 338f219747dSAndre Fischer print STDERR "can not open release description '%s'\n", $description_filename; 339f219747dSAndre Fischer $error = 1; 340f219747dSAndre Fischer } 341f219747dSAndre Fischer } 342f219747dSAndre Fischer } 343f219747dSAndre Fischer 344f219747dSAndre Fischer if ( ! defined $description_filename) 345f219747dSAndre Fischer { 346f219747dSAndre Fischer $error = 1; 347f219747dSAndre Fischer } 3481108b05eSAndre Fischer if (! defined $command) 3491108b05eSAndre Fischer { 3501108b05eSAndre Fischer printf STDERR "ERROR: no command\n"; 3511108b05eSAndre Fischer $error = 1; 3521108b05eSAndre Fischer } 3531108b05eSAndre Fischer elsif ($command =~ /^(wiki)$/) 354f219747dSAndre Fischer { 355f219747dSAndre Fischer if ( ! defined $output_filename) 356f219747dSAndre Fischer { 357f219747dSAndre Fischer printf STDERR "ERROR: no output filename\n", 358f219747dSAndre Fischer $error = 1; 359f219747dSAndre Fischer } 360f219747dSAndre Fischer } 361f219747dSAndre Fischer 362f219747dSAndre Fischer if ($error) 363f219747dSAndre Fischer { 364f219747dSAndre Fischer PrintUsageAndExit(); 365f219747dSAndre Fischer } 366f219747dSAndre Fischer 367f219747dSAndre Fischer return { 368f219747dSAndre Fischer 'command' => $command, 369f219747dSAndre Fischer 'filename' => $description_filename, 370f219747dSAndre Fischer 'max-process-count' => $max_process_count, 371f219747dSAndre Fischer 'keep-going' => $keep_going, 372f219747dSAndre Fischer 'upload-destination' => $upload_destination, 373f219747dSAndre Fischer 'check-links' => $check_links, 374f219747dSAndre Fischer 'mark-broken-links' => $mark_broken_links, 3759dd622cdSAndre Fischer 'output-filename' => $output_filename, 3769dd622cdSAndre Fischer 'max-upload-count' => $max_upload_count, 3779dd622cdSAndre Fischer 'build-only-missing' => $build_only_missing, 3789dd622cdSAndre Fischer 'dry-run' => $dry_run 379f219747dSAndre Fischer }; 380f219747dSAndre Fischer} 381f219747dSAndre Fischer 382f219747dSAndre Fischer 383f219747dSAndre Fischer 384f219747dSAndre Fischer 385f219747dSAndre Fischersub PrintUsageAndExit () 386f219747dSAndre Fischer{ 387f219747dSAndre Fischer print STDERR "usage: $0 <command> {option} <release-description.xml>\n"; 388f219747dSAndre Fischer print STDERR " comands:\n"; 389f219747dSAndre Fischer print STDERR " build\n"; 3909dd622cdSAndre Fischer print STDERR " build-missing\n"; 391f219747dSAndre Fischer print STDERR " upload\n"; 392f219747dSAndre Fischer print STDERR " wiki create a download page in MediaWiki syntax\n"; 393f219747dSAndre Fischer print STDERR " options:\n"; 394f219747dSAndre Fischer print STDERR " -j <count> maximum number of build processes\n"; 395f219747dSAndre Fischer print STDERR " -k keep going if there are recoverable errors\n"; 396f219747dSAndre Fischer print STDERR " -u <path> upload destination\n"; 397f219747dSAndre Fischer print STDERR " -l check links on wiki page, write broken links as plain text\n"; 398f219747dSAndre Fischer print STDERR " -ld check links on wiki page, mark broken links\n"; 399f219747dSAndre Fischer print STDERR " -o <filename> filename of the output (wiki: wiki page, build: makefile)\n"; 4009dd622cdSAndre Fischer print STDERR " -n <number> maximal number of upload tries, defaults to 5.\n"; 4019dd622cdSAndre Fischer print STDERR " -d dry run\n"; 402f219747dSAndre Fischer exit(1); 403f219747dSAndre Fischer} 404f219747dSAndre Fischer 405f219747dSAndre Fischer 406f219747dSAndre Fischer 407f219747dSAndre Fischer 4089dd622cdSAndre Fischer=head2 Trim ($text) 4099dd622cdSAndre Fischer 4109dd622cdSAndre Fischer Remove leading and trailing space from the given string. 4119dd622cdSAndre Fischer 4129dd622cdSAndre Fischer=cut 413f219747dSAndre Fischersub Trim ($) 414f219747dSAndre Fischer{ 415f219747dSAndre Fischer my ($text) = @_; 416f219747dSAndre Fischer $text =~ s/^\s+|\s+$//g; 417f219747dSAndre Fischer return $text; 418f219747dSAndre Fischer} 419f219747dSAndre Fischer 420f219747dSAndre Fischer 421f219747dSAndre Fischer 422f219747dSAndre Fischer 4239dd622cdSAndre Fischer=head2 ReadReleaseDescription ($$) 4249dd622cdSAndre Fischer 4259dd622cdSAndre Fischer Read the release description from $filename. 4269dd622cdSAndre Fischer 4279dd622cdSAndre Fischer=cut 428f219747dSAndre Fischersub ReadReleaseDescription ($$) 429f219747dSAndre Fischer{ 430f219747dSAndre Fischer my ($filename, $context) = @_; 431f219747dSAndre Fischer 432f219747dSAndre Fischer my $document = XML::LibXML->load_xml('location' => $filename); 433f219747dSAndre Fischer my $root = $document->documentElement(); 434f219747dSAndre Fischer 435f219747dSAndre Fischer # Initialize the release description. 436f219747dSAndre Fischer my $release = { 437f219747dSAndre Fischer 'name' => $root->getAttribute("name"), 438f219747dSAndre Fischer 'version' => $root->getAttribute("version"), 4391108b05eSAndre Fischer 'previous-version' => $root->getAttribute("previous-version"), 440f219747dSAndre Fischer 'builds' => [], 441f219747dSAndre Fischer 'languages' => {}, 442f219747dSAndre Fischer 'language-ids' => [], 443f219747dSAndre Fischer 'platforms' => {}, 4449dd622cdSAndre Fischer 'downloads' => [], 4459dd622cdSAndre Fischer 'packages' => {}, 446f219747dSAndre Fischer 'platform-ids' => [], 4479dd622cdSAndre Fischer 'wiki-packages' => [] 448f219747dSAndre Fischer }; 449f219747dSAndre Fischer 450f219747dSAndre Fischer # Process the language descriptions. 451f219747dSAndre Fischer for my $language_element ($root->getChildrenByTagName("language")) 452f219747dSAndre Fischer { 453f219747dSAndre Fischer my $language_descriptor = ProcessLanguageDescription($language_element, $context); 454f219747dSAndre Fischer $release->{'languages'}->{$language_descriptor->{'id'}} = $language_descriptor; 455f219747dSAndre Fischer push @{$release->{'language-ids'}}, $language_descriptor->{'id'}; 456f219747dSAndre Fischer } 457f219747dSAndre Fischer printf "%d languages\n", scalar keys %{$release->{'languages'}}; 458f219747dSAndre Fischer 459f219747dSAndre Fischer # Process the platform descriptions. 460f219747dSAndre Fischer for my $platform_element ($root->getChildrenByTagName("platform")) 461f219747dSAndre Fischer { 4629dd622cdSAndre Fischer my $platform_descriptor = ProcessPlatformDescription($platform_element, $context); 4639dd622cdSAndre Fischer $release->{'platforms'}->{$platform_descriptor->{'id'}} = $platform_descriptor; 4649dd622cdSAndre Fischer push @{$release->{'platform-ids'}}, $platform_descriptor->{'id'}; 465f219747dSAndre Fischer } 466f219747dSAndre Fischer printf "%d platforms\n", scalar keys %{$release->{'platforms'}}; 467f219747dSAndre Fischer 4689dd622cdSAndre Fischer # Process the package descriptions. 4699dd622cdSAndre Fischer for my $package_element ($root->getChildrenByTagName("package")) 4709dd622cdSAndre Fischer { 4719dd622cdSAndre Fischer my $package_descriptor = ProcessPackageDescription($package_element, $context); 4729dd622cdSAndre Fischer $release->{'packages'}->{$package_descriptor->{'id'}} = $package_descriptor; 4739dd622cdSAndre Fischer } 4749dd622cdSAndre Fischer printf "%d packages\n", scalar keys %{$release->{'packages'}}; 4759dd622cdSAndre Fischer 4761108b05eSAndre Fischer # Platform specific the package descriptions. 4771108b05eSAndre Fischer for my $package_element ($root->getChildrenByTagName("platform-package")) 4781108b05eSAndre Fischer { 4791108b05eSAndre Fischer my $package_descriptor = ProcessPlatformPackageDescription($package_element, $context); 4801108b05eSAndre Fischer my $key = $package_descriptor->{'platform-id'} . "/" . $package_descriptor->{'package-id'}; 4811108b05eSAndre Fischer $release->{'platform-packages'}->{$key} = $package_descriptor; 4821108b05eSAndre Fischer } 4831108b05eSAndre Fischer printf "%d platform packages\n", scalar keys %{$release->{'platform-packages'}}; 4841108b05eSAndre Fischer 4859dd622cdSAndre Fischer # Process the download descriptions. 4869dd622cdSAndre Fischer for my $download_element ($root->getChildrenByTagName("download")) 4879dd622cdSAndre Fischer { 4889dd622cdSAndre Fischer my $download_descriptor = ProcessDownloadDescription($download_element, $context); 4899dd622cdSAndre Fischer push @{$release->{'downloads'}}, $download_descriptor; 4909dd622cdSAndre Fischer } 4919dd622cdSAndre Fischer printf "%d downloads\n", scalar @{$release->{'downloads'}}; 4929dd622cdSAndre Fischer 493f219747dSAndre Fischer if ($context->{'command'} =~ /^(build|upload)$/) 494f219747dSAndre Fischer { 495f219747dSAndre Fischer # Process the build descriptions. 496f219747dSAndre Fischer for my $build_element ($root->getChildrenByTagName("build")) 497f219747dSAndre Fischer { 498f219747dSAndre Fischer push @{$release->{'builds'}}, ProcessBuildDescription($build_element, $context, $release); 499f219747dSAndre Fischer } 500f219747dSAndre Fischer printf "%d build targets\n", scalar @{$release->{'builds'}}; 501f219747dSAndre Fischer } 502f219747dSAndre Fischer 503f219747dSAndre Fischer if ($context->{'command'} eq "wiki") 504f219747dSAndre Fischer { 505f219747dSAndre Fischer for my $wiki_element ($root->getChildrenByTagName("wiki")) 506f219747dSAndre Fischer { 5079dd622cdSAndre Fischer for my $wiki_package_element ($wiki_element->getChildrenByTagName("package-ref")) 508f219747dSAndre Fischer { 509f219747dSAndre Fischer my $wiki_package = ProcessWikiPackageDescription( 510f219747dSAndre Fischer $wiki_package_element, 511f219747dSAndre Fischer $context, 512f219747dSAndre Fischer $release); 513f219747dSAndre Fischer push @{$release->{'wiki-packages'}}, $wiki_package; 514f219747dSAndre Fischer } 515f219747dSAndre Fischer } 516f219747dSAndre Fischer printf "%d wiki packages\n", scalar @{$release->{'wiki-packages'}}; 517f219747dSAndre Fischer } 518f219747dSAndre Fischer 519f219747dSAndre Fischer return $release; 520f219747dSAndre Fischer} 521f219747dSAndre Fischer 522f219747dSAndre Fischer 523f219747dSAndre Fischer 524f219747dSAndre Fischer 5259dd622cdSAndre Fischer=head ProcessBuildDescription ($build_element, $context, $release_descriptor) 5269dd622cdSAndre Fischer 5279dd622cdSAndre Fischer Process one <build> element. 5289dd622cdSAndre Fischer 5299dd622cdSAndre Fischer If its platform-list does not match the current platform then the <build> element is ignored. 5309dd622cdSAndre Fischer 5319dd622cdSAndre Fischer=cut 532f219747dSAndre Fischersub ProcessBuildDescription ($$$) 533f219747dSAndre Fischer{ 534f219747dSAndre Fischer my ($build_element, $context, $release_descriptor) = @_; 535f219747dSAndre Fischer 5369dd622cdSAndre Fischer my $package_id = $build_element->getAttribute("package-id"); 537f219747dSAndre Fischer my $languages = PostprocessLanguageList($build_element->getAttribute("language-list"), $release_descriptor); 538f219747dSAndre Fischer my $platforms = PostprocessPlatformList($build_element->getAttribute("platform-list"), $release_descriptor); 539f219747dSAndre Fischer 540f219747dSAndre Fischer # Check if the platform matches any for which the product shall be built. 541f219747dSAndre Fischer my $current_platform = $ENV{'INPATH'}; 542f219747dSAndre Fischer my $is_platform_match = 0; 543f219747dSAndre Fischer foreach my $platform_id (@$platforms) 544f219747dSAndre Fischer { 545f219747dSAndre Fischer if ($platform_id eq $current_platform) 546f219747dSAndre Fischer { 547f219747dSAndre Fischer $is_platform_match=1; 548f219747dSAndre Fischer last; 549f219747dSAndre Fischer } 550f219747dSAndre Fischer } 551f219747dSAndre Fischer if ($is_platform_match) 552f219747dSAndre Fischer { 5539dd622cdSAndre Fischer printf "including build %s\n", $package_id; 554f219747dSAndre Fischer } 555f219747dSAndre Fischer else 556f219747dSAndre Fischer { 5579dd622cdSAndre Fischer printf "skipping build %s: no platform match\n", $package_id; 558f219747dSAndre Fischer printf "none of the platforms %s matches %s\n", 5599dd622cdSAndre Fischer join(", ", keys %{$release_descriptor->{'platforms'}}), 5609dd622cdSAndre Fischer $current_platform; 561f219747dSAndre Fischer return; 562f219747dSAndre Fischer } 563f219747dSAndre Fischer 564f219747dSAndre Fischer my @languages = CheckLanguageSet($context, @$languages); 565f219747dSAndre Fischer 566f219747dSAndre Fischer return { 5679dd622cdSAndre Fischer 'package-id' => $package_id, 5689dd622cdSAndre Fischer 'platform-list' => $platforms, 569f219747dSAndre Fischer 'language-list' => \@languages 570f219747dSAndre Fischer }; 571f219747dSAndre Fischer} 572f219747dSAndre Fischer 573f219747dSAndre Fischer 574f219747dSAndre Fischer 575f219747dSAndre Fischer 5769dd622cdSAndre Fischer 5779dd622cdSAndre Fischer=head2 ProcessPlatformDescription ($element, $context) 5789dd622cdSAndre Fischer 5799dd622cdSAndre Fischer Process one <platform> element. 5809dd622cdSAndre Fischer 5819dd622cdSAndre Fischer The corresponding platform descriptor is returned as a hash. 5829dd622cdSAndre Fischer 5839dd622cdSAndre Fischer=cut 584f219747dSAndre Fischersub ProcessPlatformDescription ($$) 585f219747dSAndre Fischer{ 586f219747dSAndre Fischer my ($element, $context) = @_; 587f219747dSAndre Fischer 588f219747dSAndre Fischer my $descriptor = {}; 589f219747dSAndre Fischer # Mandatory tags. 5909dd622cdSAndre Fischer foreach my $id ("id", "display-name", "archive-platform", "word-size", "package-types") 591f219747dSAndre Fischer { 592f219747dSAndre Fischer $descriptor->{$id} = $element->getAttribute($id); 5939dd622cdSAndre Fischer die "release/platform has no attribute $id" unless defined $descriptor->{$id}; 594f219747dSAndre Fischer } 5959dd622cdSAndre Fischer # Optional tags. 5969dd622cdSAndre Fischer foreach my $id ("extension", "add-package-type-to-archive-name") 5979dd622cdSAndre Fischer { 5981108b05eSAndre Fischer my $value = $element->getAttribute($id); 5991108b05eSAndre Fischer $descriptor->{$id} = $value if defined $value; 6009dd622cdSAndre Fischer } 6019dd622cdSAndre Fischer 6021108b05eSAndre Fischer $descriptor->{'add-package-type-to-archive-name'} = 0 6031108b05eSAndre Fischer unless defined $descriptor->{'add-package-type-to-archive-name'}; 6049dd622cdSAndre Fischer $descriptor->{'package-types'} = [split(/;/, $descriptor->{'package-types'})]; 6059dd622cdSAndre Fischer 6069dd622cdSAndre Fischer return $descriptor; 6079dd622cdSAndre Fischer} 6089dd622cdSAndre Fischer 6099dd622cdSAndre Fischer 6109dd622cdSAndre Fischer 6119dd622cdSAndre Fischer 6129dd622cdSAndre Fischer=head2 ProcessDownloadDescription ($element, $context) 6139dd622cdSAndre Fischer 6149dd622cdSAndre Fischer Process one <download> element. 6159dd622cdSAndre Fischer 6169dd622cdSAndre Fischer The corresponding download descriptor is returned as a hash. 6179dd622cdSAndre Fischer 6189dd622cdSAndre Fischer=cut 6199dd622cdSAndre Fischersub ProcessDownloadDescription ($$) 6209dd622cdSAndre Fischer{ 6219dd622cdSAndre Fischer my ($element, $context) = @_; 622f219747dSAndre Fischer 6239dd622cdSAndre Fischer my $descriptor = {}; 6249dd622cdSAndre Fischer 6259dd622cdSAndre Fischer # Mandatory tags. 6269dd622cdSAndre Fischer foreach my $id ("platform-id", "base-url") 627f219747dSAndre Fischer { 6289dd622cdSAndre Fischer $descriptor->{$id} = $element->getAttribute($id); 6299dd622cdSAndre Fischer die "release/download has no attribute $id" unless defined $descriptor->{$id}; 630f219747dSAndre Fischer } 631f219747dSAndre Fischer 6329dd622cdSAndre Fischer return $descriptor; 633f219747dSAndre Fischer} 634f219747dSAndre Fischer 635f219747dSAndre Fischer 636f219747dSAndre Fischer 637f219747dSAndre Fischer 6389dd622cdSAndre Fischer=head2 ProcessPackageDescription ($element, $context) 6399dd622cdSAndre Fischer 6409dd622cdSAndre Fischer Process one <package> element. 6419dd622cdSAndre Fischer 6429dd622cdSAndre Fischer The corresponding package descriptor is returned as a hash. 6439dd622cdSAndre Fischer 6449dd622cdSAndre Fischer=cut 6451108b05eSAndre Fischersub ProcessPackageDescription ($$) 646f219747dSAndre Fischer{ 6471108b05eSAndre Fischer my ($element, $context) = @_; 648f219747dSAndre Fischer 649f219747dSAndre Fischer my $descriptor = {}; 6509dd622cdSAndre Fischer 651f219747dSAndre Fischer # Mandatory tags. 6521108b05eSAndre Fischer foreach my $id ("id", "target", "archive-path", "archive-name", "display-name") 653f219747dSAndre Fischer { 654f219747dSAndre Fischer $descriptor->{$id} = $element->getAttribute($id); 6559dd622cdSAndre Fischer die "release/package has no attribute $id" unless defined $descriptor->{$id}; 6569dd622cdSAndre Fischer die "release/package attribute $id is empty" unless $descriptor->{$id} !~ /^\s*$/; 657f219747dSAndre Fischer } 658f219747dSAndre Fischer # Optional tags. 6599dd622cdSAndre Fischer foreach my $id ("link-tooltip", "link-URL", "download-extension") 6601108b05eSAndre Fischer { 6611108b05eSAndre Fischer my $value = $element->getAttribute($id); 6621108b05eSAndre Fischer $descriptor->{$id} = $value if defined $value; 6631108b05eSAndre Fischer } 6641108b05eSAndre Fischer 6651108b05eSAndre Fischer return $descriptor; 6661108b05eSAndre Fischer} 6671108b05eSAndre Fischer 6681108b05eSAndre Fischer 6691108b05eSAndre Fischer 6701108b05eSAndre Fischer 6711108b05eSAndre Fischer=head2 ProcessPlatformPackageDescription ($element, $context) 6721108b05eSAndre Fischer 6731108b05eSAndre Fischer Process one <platform-package> element. 6741108b05eSAndre Fischer 6751108b05eSAndre Fischer The corresponding package descriptor is returned as a hash. 6761108b05eSAndre Fischer 6771108b05eSAndre Fischer=cut 6781108b05eSAndre Fischersub ProcessPlatformPackageDescription ($$) 6791108b05eSAndre Fischer{ 6801108b05eSAndre Fischer my ($element, $context) = @_; 6811108b05eSAndre Fischer 6821108b05eSAndre Fischer my $descriptor = {}; 6831108b05eSAndre Fischer 6841108b05eSAndre Fischer # Mandatory tags. 6851108b05eSAndre Fischer foreach my $id ("platform-id", "package-id") 6869dd622cdSAndre Fischer { 6879dd622cdSAndre Fischer $descriptor->{$id} = $element->getAttribute($id); 6881108b05eSAndre Fischer die "release/package has no attribute $id" unless defined $descriptor->{$id}; 6891108b05eSAndre Fischer die "release/package attribute $id is empty" unless $descriptor->{$id} !~ /^\s*$/; 6901108b05eSAndre Fischer } 6911108b05eSAndre Fischer # Optional tags. 6921108b05eSAndre Fischer foreach my $id ("extension", "package-types") 6931108b05eSAndre Fischer { 6941108b05eSAndre Fischer my $value = $element->getAttribute($id); 6951108b05eSAndre Fischer $descriptor->{$id} = $value if defined $value; 6961108b05eSAndre Fischer } 6971108b05eSAndre Fischer if (defined $descriptor->{'package-types'}) 6981108b05eSAndre Fischer { 6991108b05eSAndre Fischer $descriptor->{'package-types'} = [split(/;/, $descriptor->{'package-types'})]; 7009dd622cdSAndre Fischer } 7019dd622cdSAndre Fischer 7029dd622cdSAndre Fischer return $descriptor; 7039dd622cdSAndre Fischer} 7049dd622cdSAndre Fischer 7059dd622cdSAndre Fischer 7069dd622cdSAndre Fischer 7079dd622cdSAndre Fischer 7089dd622cdSAndre Fischer=head2 ProcessWikiPackageDescription ($element, $context) 7099dd622cdSAndre Fischer 7109dd622cdSAndre Fischer Process one <wiki><package-ref> element. 7119dd622cdSAndre Fischer 7129dd622cdSAndre Fischer The corresponding descriptor is returned as a hash. 7139dd622cdSAndre Fischer 7149dd622cdSAndre Fischer=cut 7159dd622cdSAndre Fischersub ProcessWikiPackageDescription ($$$) 7169dd622cdSAndre Fischer{ 7179dd622cdSAndre Fischer my ($element, $context, $release_descriptor) = @_; 7189dd622cdSAndre Fischer 7199dd622cdSAndre Fischer my $descriptor = {}; 7209dd622cdSAndre Fischer # Mandatory tags. 7219dd622cdSAndre Fischer foreach my $id ("package-id", "table") 722f219747dSAndre Fischer { 723f219747dSAndre Fischer $descriptor->{$id} = $element->getAttribute($id); 7249dd622cdSAndre Fischer die "wiki/package-ref has no attribute $id" unless defined $descriptor->{$id}; 7259dd622cdSAndre Fischer die "wiki/package-ref attribute $id is empty" unless $descriptor->{$id} !~ /^\s*$/; 726f219747dSAndre Fischer } 727f219747dSAndre Fischer 728f219747dSAndre Fischer $descriptor->{'language-list'} = PostprocessLanguageList( 729f219747dSAndre Fischer $element->getAttribute("language-list"), 730f219747dSAndre Fischer $release_descriptor); 731f219747dSAndre Fischer $descriptor->{'platform-list'} = PostprocessPlatformList( 732f219747dSAndre Fischer $element->getAttribute("platform-list"), 733f219747dSAndre Fischer $release_descriptor); 734f219747dSAndre Fischer 735f219747dSAndre Fischer $descriptor->{'languages'} = {map{$_=>1} @{$descriptor->{'language-list'}}}; 736f219747dSAndre Fischer $descriptor->{'platforms'} = {map{$_=>1} @{$descriptor->{'platform-list'}}}; 737f219747dSAndre Fischer 738f219747dSAndre Fischer return $descriptor; 739f219747dSAndre Fischer} 740f219747dSAndre Fischer 741f219747dSAndre Fischer 742f219747dSAndre Fischer 743f219747dSAndre Fischer 7449dd622cdSAndre Fischer=head2 ProcessLanguageDescription ($element, $context) 7459dd622cdSAndre Fischer 7469dd622cdSAndre Fischer Process one <language> element. 7479dd622cdSAndre Fischer 7489dd622cdSAndre Fischer The corresponding language descriptor is returned as a hash. 7499dd622cdSAndre Fischer 7509dd622cdSAndre Fischer=cut 751f219747dSAndre Fischersub ProcessLanguageDescription ($$) 752f219747dSAndre Fischer{ 753f219747dSAndre Fischer my ($element, $context) = @_; 754f219747dSAndre Fischer 755f219747dSAndre Fischer my $descriptor = {}; 756f219747dSAndre Fischer foreach my $id ("id", "english-name", "local-name") 757f219747dSAndre Fischer { 758f219747dSAndre Fischer $descriptor->{$id} = $element->getAttribute($id); 759f219747dSAndre Fischer die "wiki/language has no attribute $id" unless defined $descriptor->{$id}; 760f219747dSAndre Fischer } 761f219747dSAndre Fischer 762f219747dSAndre Fischer return $descriptor; 763f219747dSAndre Fischer} 764f219747dSAndre Fischer 765f219747dSAndre Fischer 766f219747dSAndre Fischer 767f219747dSAndre Fischer 7689dd622cdSAndre Fischer=head2 PostprocessLanguageList ($language_list, $release_descriptor) 7699dd622cdSAndre Fischer 7709dd622cdSAndre Fischer Process a language list that is given as 'language-list' attribute to some tags. 7719dd622cdSAndre Fischer 7729dd622cdSAndre Fischer If the attribute is missing, ie $language_list is undef, or its value is "all", 7739dd622cdSAndre Fischer then the returned list of languages is set to all languages defined via <language> elements. 7749dd622cdSAndre Fischer 7759dd622cdSAndre Fischer=cut 776f219747dSAndre Fischersub PostprocessLanguageList ($$) 777f219747dSAndre Fischer{ 778f219747dSAndre Fischer my ($language_list, $release_descriptor) = @_; 779f219747dSAndre Fischer 780f219747dSAndre Fischer my @matching_languages = (); 781f219747dSAndre Fischer if ( ! defined $language_list 782f219747dSAndre Fischer || $language_list eq "all") 783f219747dSAndre Fischer { 784f219747dSAndre Fischer @matching_languages = sort keys %{$release_descriptor->{'languages'}}; 785f219747dSAndre Fischer } 786f219747dSAndre Fischer else 787f219747dSAndre Fischer { 788f219747dSAndre Fischer @matching_languages = split(/;/, $language_list); 789f219747dSAndre Fischer } 790f219747dSAndre Fischer 791f219747dSAndre Fischer return \@matching_languages; 792f219747dSAndre Fischer} 793f219747dSAndre Fischer 794f219747dSAndre Fischer 795f219747dSAndre Fischer 796f219747dSAndre Fischer 7979dd622cdSAndre Fischer=head2 PostprocessPlatformList ($platform_list, $release_descriptor) 7989dd622cdSAndre Fischer 7999dd622cdSAndre Fischer Process a platform list that is given as 'platform-list' attribute to some tags. 8009dd622cdSAndre Fischer 8019dd622cdSAndre Fischer If the attribute is missing, ie $platform_list is undef, or its value is "all", 8029dd622cdSAndre Fischer then the returned list of platforms is set to all platforms defined via <platform> elements. 8039dd622cdSAndre Fischer 8049dd622cdSAndre Fischer=cut 805f219747dSAndre Fischersub PostprocessPlatformList ($$) 806f219747dSAndre Fischer{ 807f219747dSAndre Fischer my ($platform_list, $release_descriptor) = @_; 808f219747dSAndre Fischer 809f219747dSAndre Fischer my @matching_platforms = (); 810f219747dSAndre Fischer if ( ! defined $platform_list 811f219747dSAndre Fischer || $platform_list eq "all") 812f219747dSAndre Fischer { 813f219747dSAndre Fischer @matching_platforms = sort keys %{$release_descriptor->{'platforms'}}; 814f219747dSAndre Fischer } 815f219747dSAndre Fischer else 816f219747dSAndre Fischer { 817f219747dSAndre Fischer @matching_platforms = split(/;/, $platform_list); 818f219747dSAndre Fischer } 819f219747dSAndre Fischer 820f219747dSAndre Fischer return \@matching_platforms; 821f219747dSAndre Fischer} 822f219747dSAndre Fischer 823f219747dSAndre Fischer 824f219747dSAndre Fischer 825f219747dSAndre Fischer 8269dd622cdSAndre Fischer=head2 CheckLanguageSet ($context, @languages) 8279dd622cdSAndre Fischer 8289dd622cdSAndre Fischer Compare the given list of languages with the one defined by the 'WITH_LANG' environment variable. 8299dd622cdSAndre Fischer 8309dd622cdSAndre Fischer This is to ensure that configure --with-lang was called with the same set of languages that are 8319dd622cdSAndre Fischer listed by the <language> elements. 8329dd622cdSAndre Fischer 8339dd622cdSAndre Fischer=cut 834f219747dSAndre Fischersub CheckLanguageSet ($@) 835f219747dSAndre Fischer{ 836f219747dSAndre Fischer my ($context, @languages) = @_; 837f219747dSAndre Fischer my %configured_languages = map{$_=>1} split(/\s+/, $ENV{'WITH_LANG'}); 838f219747dSAndre Fischer 839f219747dSAndre Fischer my @missing_languages = (); 840f219747dSAndre Fischer my @present_languages = (); 841f219747dSAndre Fischer for my $language (@languages) 842f219747dSAndre Fischer { 843f219747dSAndre Fischer if (defined $configured_languages{$language}) 844f219747dSAndre Fischer { 845f219747dSAndre Fischer push @present_languages, $language; 846f219747dSAndre Fischer } 847f219747dSAndre Fischer else 848f219747dSAndre Fischer { 849f219747dSAndre Fischer push @missing_languages, $language; 850f219747dSAndre Fischer } 851f219747dSAndre Fischer } 852f219747dSAndre Fischer 853f219747dSAndre Fischer if (scalar @missing_languages > 0) 854f219747dSAndre Fischer { 8559dd622cdSAndre Fischer my $message_head = $context->{'keep-going'} ? "WARNING" : "ERROR"; 8569dd622cdSAndre Fischer printf STDERR "%s: there are languages that where not configured via --with-lang:\n", $message_head; 8579dd622cdSAndre Fischer printf STDERR "%s: %s\n", $message_head, join(", ", @missing_languages); 858f219747dSAndre Fischer if ($context->{'keep-going'}) 859f219747dSAndre Fischer { 860f219747dSAndre Fischer printf " available languages:\n"; 861f219747dSAndre Fischer printf " %s\n", join(", ", @present_languages); 862f219747dSAndre Fischer } 863f219747dSAndre Fischer else 864f219747dSAndre Fischer { 8659dd622cdSAndre Fischer printf STDERR "ERROR: please rerun configure with --with-lang=\"%s\"\n", join(" ", @languages); 8669dd622cdSAndre Fischer exit(1); 867f219747dSAndre Fischer } 868f219747dSAndre Fischer } 869f219747dSAndre Fischer 870f219747dSAndre Fischer return @present_languages; 871f219747dSAndre Fischer} 872f219747dSAndre Fischer 873f219747dSAndre Fischer 874f219747dSAndre Fischer 875f219747dSAndre Fischer 8761108b05eSAndre Fischer=head2 WriteMakefile ($release_descriptor, $context) 8779dd622cdSAndre Fischer 8789dd622cdSAndre Fischer Write a makefile with all targets that match the <build> elements. 8799dd622cdSAndre Fischer 8809dd622cdSAndre Fischer The use of a makefile allows us to use make to handle concurrent building. 8819dd622cdSAndre Fischer 8829dd622cdSAndre Fischer When an output file was specified on the command line (option -o) then the 8839dd622cdSAndre Fischer makefile is written to that file but make is not run. 8849dd622cdSAndre Fischer 8859dd622cdSAndre Fischer When no output file was specified then the makefile is written to a temporary 8869dd622cdSAndre Fischer file. Then make is run for this makefile. 8879dd622cdSAndre Fischer 8889dd622cdSAndre Fischer=cut 889f219747dSAndre Fischersub WriteMakefile ($$) 890f219747dSAndre Fischer{ 8911108b05eSAndre Fischer my ($release_descriptor, $context) = @_; 892f219747dSAndre Fischer 8939dd622cdSAndre Fischer my $filename = $context->{'output-filename'}; 8949dd622cdSAndre Fischer if ( ! defined $filename) 8959dd622cdSAndre Fischer { 8969dd622cdSAndre Fischer $filename = File::Temp->new(); 8979dd622cdSAndre Fischer } 898f219747dSAndre Fischer 8999dd622cdSAndre Fischer # Collect the targets to make. 9009dd622cdSAndre Fischer my @targets = (); 9011108b05eSAndre Fischer foreach my $build (@{$release_descriptor->{'builds'}}) 902f219747dSAndre Fischer { 9031108b05eSAndre Fischer my $platform_descriptor = GetCurrentPlatformDescriptor($release_descriptor); 9041108b05eSAndre Fischer my $package_descriptor = $release_descriptor->{'packages'}->{$build->{'package-id'}}; 9051108b05eSAndre Fischer my $platform_package_descriptor = GetPlatformPackage( 9061108b05eSAndre Fischer $release_descriptor, 9071108b05eSAndre Fischer $platform_descriptor, 9081108b05eSAndre Fischer $package_descriptor); 9091108b05eSAndre Fischer 9109dd622cdSAndre Fischer foreach my $language_id (@{$build->{'language-list'}}) 911f219747dSAndre Fischer { 9121108b05eSAndre Fischer foreach my $package_format (@{$platform_package_descriptor->{'package-types'}}) 9139dd622cdSAndre Fischer { 9149dd622cdSAndre Fischer my $full_target = sprintf("%s_%s.%s", 9159dd622cdSAndre Fischer $package_descriptor->{'target'}, 9169dd622cdSAndre Fischer $language_id, 9179dd622cdSAndre Fischer $package_format); 9189dd622cdSAndre Fischer if ($context->{'build-only-missing'}) 9199dd622cdSAndre Fischer { 9201108b05eSAndre Fischer my ($archive_path, $archive_name) = GetInstallationPackageName( 9211108b05eSAndre Fischer $release_descriptor, 9221108b05eSAndre Fischer $platform_package_descriptor, 9239dd622cdSAndre Fischer $package_format, 9249dd622cdSAndre Fischer $language_id); 9251108b05eSAndre Fischer my $candidate = $archive_path . "/" . $archive_name; 9269dd622cdSAndre Fischer if (-f $candidate) 9279dd622cdSAndre Fischer { 9289dd622cdSAndre Fischer printf "download set for %s already exists, skipping\n", $full_target; 9299dd622cdSAndre Fischer next; 9309dd622cdSAndre Fischer } 9311108b05eSAndre Fischer else 9321108b05eSAndre Fischer { 9331108b05eSAndre Fischer printf "%s %s\n", $archive_path, $archive_name; 9341108b05eSAndre Fischer } 9359dd622cdSAndre Fischer } 9369dd622cdSAndre Fischer push @targets, $full_target; 9379dd622cdSAndre Fischer } 938f219747dSAndre Fischer } 939f219747dSAndre Fischer } 9409dd622cdSAndre Fischer 9419dd622cdSAndre Fischer # Write the makefile. 9429dd622cdSAndre Fischer open my $make, ">", $filename; 9439dd622cdSAndre Fischer 9449dd622cdSAndre Fischer # Write dependencies of 'all' on the products in all languages. 9459dd622cdSAndre Fischer print $make "all .PHONY : \\\n "; 9469dd622cdSAndre Fischer printf $make "%s\n", join(" \\\n ", @targets); 947f219747dSAndre Fischer printf $make "\n\n"; 948f219747dSAndre Fischer 9499dd622cdSAndre Fischer if ($context->{'dry-run'}) 9509dd622cdSAndre Fischer { 9519dd622cdSAndre Fischer printf ("adding make fules for\n %s\n", join("\n ", @targets)); 9529dd622cdSAndre Fischer } 9539dd622cdSAndre Fischer 954f219747dSAndre Fischer # Write rules that chain dmake in instsetoo_native/util. 9559dd622cdSAndre Fischer foreach my $target (@targets) 9569dd622cdSAndre Fischer { 9579dd622cdSAndre Fischer printf $make "%s :\n", $target; 9589dd622cdSAndre Fischer printf $make "\tdmake \$@ release=t\n"; 9599dd622cdSAndre Fischer } 9609dd622cdSAndre Fischer close $make; 9619dd622cdSAndre Fischer 9629dd622cdSAndre Fischer 9639dd622cdSAndre Fischer if ( ! defined $context->{'output-filename'}) 964f219747dSAndre Fischer { 9659dd622cdSAndre Fischer # Caller wants us to run make. 9669dd622cdSAndre Fischer my $path = $ENV{'SRC_ROOT'} . "/instsetoo_native/util"; 9679dd622cdSAndre Fischer my $command = sprintf("make -f \"%s\" -C \"%s\" -j%d", 9689dd622cdSAndre Fischer $filename, 9699dd622cdSAndre Fischer $path, 9709dd622cdSAndre Fischer $context->{'max-process-count'}); 9719dd622cdSAndre Fischer if ($context->{'dry-run'}) 972f219747dSAndre Fischer { 9739dd622cdSAndre Fischer printf "would run %s\n", $command; 9749dd622cdSAndre Fischer } 9759dd622cdSAndre Fischer else 9769dd622cdSAndre Fischer { 9779dd622cdSAndre Fischer printf "running %s\n", $command; 9789dd622cdSAndre Fischer system($command); 979f219747dSAndre Fischer } 980f219747dSAndre Fischer } 981f219747dSAndre Fischer} 982f219747dSAndre Fischer 983f219747dSAndre Fischer 984f219747dSAndre Fischer 985f219747dSAndre Fischer 986f219747dSAndre Fischersub Upload ($$) 987f219747dSAndre Fischer{ 9881108b05eSAndre Fischer my ($release_descriptor, $context) = @_; 989f219747dSAndre Fischer 990f219747dSAndre Fischer if ( ! defined $context->{'upload-destination'}) 991f219747dSAndre Fischer { 992f219747dSAndre Fischer printf STDERR "ERROR: upload destination is missing\n"; 993f219747dSAndre Fischer PrintUsageAndExit(); 994f219747dSAndre Fischer } 995f219747dSAndre Fischer 9961108b05eSAndre Fischer my @download_sets = CollectDownloadSets($release_descriptor); 9979dd622cdSAndre Fischer 9989dd622cdSAndre Fischer ProvideChecksums($context, @download_sets); 9999dd622cdSAndre Fischer my $source_path = PrepareUploadArea($context, @download_sets); 10009dd622cdSAndre Fischer if ( ! defined $source_path) 10019dd622cdSAndre Fischer { 10029dd622cdSAndre Fischer exit(1); 10039dd622cdSAndre Fischer } 10049dd622cdSAndre Fischer if ( ! UploadFilesViaRsync($context, $source_path, @download_sets)) 10059dd622cdSAndre Fischer { 10069dd622cdSAndre Fischer exit(1); 10079dd622cdSAndre Fischer } 10089dd622cdSAndre Fischer} 10099dd622cdSAndre Fischer 10109dd622cdSAndre Fischer 10119dd622cdSAndre Fischer 10129dd622cdSAndre Fischer 10139dd622cdSAndre Fischer=head2 PrepareUploadArea ($context, @download_sets) 10149dd622cdSAndre Fischer 10159dd622cdSAndre Fischer Create a temporary directory with the same sub directory strcuture that is requested in the upload location. 10169dd622cdSAndre Fischer The files that are to be uploaded are not copied but linked into this temporary directory tree. 10179dd622cdSAndre Fischer 10189dd622cdSAndre Fischer Returns the name of the temporary directory. 10199dd622cdSAndre Fischer 10209dd622cdSAndre Fischer=cut 10219dd622cdSAndre Fischersub PrepareUploadArea ($@) 10229dd622cdSAndre Fischer{ 10239dd622cdSAndre Fischer my ($context, @download_sets) = @_; 10249dd622cdSAndre Fischer 10259dd622cdSAndre Fischer my $tmpdir = File::Temp->newdir(); 10269dd622cdSAndre Fischer foreach my $download_set (@download_sets) 1027f219747dSAndre Fischer { 10289dd622cdSAndre Fischer foreach my $extension ("", ".md5", ".sha256", ".asc") 1029f219747dSAndre Fischer { 10309dd622cdSAndre Fischer my $basename = sprintf("%s%s", $download_set->{'archive-name'}, $extension); 10311108b05eSAndre Fischer my $source_path = $download_set->{'source-path'}; 10321108b05eSAndre Fischer my $source = sprintf("%s/%s", $source_path, $basename); 10331108b05eSAndre Fischer my $target_path = sprintf("%s/%s", $tmpdir, $download_set->{'destination-path'}); 10349dd622cdSAndre Fischer my $target = sprintf("%s/%s", $target_path, $basename); 10359dd622cdSAndre Fischer if ($context->{'dry-run'}) 1036f219747dSAndre Fischer { 10379dd622cdSAndre Fischer printf "would create link for %s\n", $basename; 10381108b05eSAndre Fischer printf " %s\n", $source_path; 10391108b05eSAndre Fischer printf " to %s\n", $target_path; 1040f219747dSAndre Fischer } 10419dd622cdSAndre Fischer else 1042f219747dSAndre Fischer { 10439dd622cdSAndre Fischer mkpath($target_path); 10449dd622cdSAndre Fischer unlink $target if ( -f $target); 10459dd622cdSAndre Fischer my $result = symlink($source, $target); 10469dd622cdSAndre Fischer if ($result != 1) 1047f219747dSAndre Fischer { 10489dd622cdSAndre Fischer printf "ERROR: can not created symbolic link to %s\n", $basename; 10499dd622cdSAndre Fischer printf " %s\n", $source; 10509dd622cdSAndre Fischer printf " -> %s\n", $target; 10519dd622cdSAndre Fischer return undef; 1052f219747dSAndre Fischer } 1053f219747dSAndre Fischer } 10549dd622cdSAndre Fischer } 10559dd622cdSAndre Fischer } 1056f219747dSAndre Fischer 10579dd622cdSAndre Fischer return $tmpdir; 10589dd622cdSAndre Fischer} 1059f219747dSAndre Fischer 10609dd622cdSAndre Fischer 10619dd622cdSAndre Fischer 10629dd622cdSAndre Fischer 10639dd622cdSAndre Fischersub UploadFilesViaRsync ($$@) 10649dd622cdSAndre Fischer{ 10659dd622cdSAndre Fischer my ($context, $source_path, @download_sets) = @_; 10669dd622cdSAndre Fischer 10679dd622cdSAndre Fischer 10689dd622cdSAndre Fischer # Collect the rsync flags. 10699dd622cdSAndre Fischer my @rsync_options = ( 10709dd622cdSAndre Fischer "-L", # Copy linked files 10719dd622cdSAndre Fischer "-a", # Transfer the local attributes and modification times. 10729dd622cdSAndre Fischer "-c", # Use checksums to compare source and destination files. 10739dd622cdSAndre Fischer "--progress", # Show a progress indicator 10749dd622cdSAndre Fischer "--partial", # Try to resume a previously failed upload 10759dd622cdSAndre Fischer ); 10769dd622cdSAndre Fischer 10779dd622cdSAndre Fischer # (Optional) Add flags for upload to ssh server 10789dd622cdSAndre Fischer my $upload_destination = $context->{'upload-destination'}; 10799dd622cdSAndre Fischer if ($upload_destination =~ /@/) 10809dd622cdSAndre Fischer { 10819dd622cdSAndre Fischer push @rsync_options, ("-e", "ssh"); 10829dd622cdSAndre Fischer } 10839dd622cdSAndre Fischer 10849dd622cdSAndre Fischer # Set up the rsync command. 10859dd622cdSAndre Fischer my $command = sprintf("rsync %s \"%s/\" \"%s\"", 10869dd622cdSAndre Fischer join(" ", @rsync_options), 10879dd622cdSAndre Fischer $source_path, 10889dd622cdSAndre Fischer $upload_destination); 10899dd622cdSAndre Fischer printf "%s\n", $command; 10909dd622cdSAndre Fischer 10919dd622cdSAndre Fischer if ($context->{'dry-run'}) 10929dd622cdSAndre Fischer { 10939dd622cdSAndre Fischer printf "would run %s up to %d times\n", $command, $context->{'max-upload-count'}; 10949dd622cdSAndre Fischer } 10959dd622cdSAndre Fischer else 10969dd622cdSAndre Fischer { 10979dd622cdSAndre Fischer # Run the command. If it fails, repeat a number of times. 10989dd622cdSAndre Fischer my $max_run_count = $context->{'max-upload-count'}; 10999dd622cdSAndre Fischer for (my $run_index=1; $run_index<=$max_run_count && scalar @download_sets>0; ++$run_index) 11009dd622cdSAndre Fischer { 11019dd622cdSAndre Fischer my $result = system($command); 11029dd622cdSAndre Fischer printf "%d %d\n", $result, $?; 11039dd622cdSAndre Fischer return 1 if $result == 0; 1104f219747dSAndre Fischer } 11059dd622cdSAndre Fischer printf "ERROR: could not upload all files without error in %d runs\n", $max_run_count; 11069dd622cdSAndre Fischer return 0; 1107f219747dSAndre Fischer } 1108f219747dSAndre Fischer} 1109f219747dSAndre Fischer 1110f219747dSAndre Fischer 1111f219747dSAndre Fischer 1112f219747dSAndre Fischer 1113f219747dSAndre Fischersub CollectDownloadSets ($) 1114f219747dSAndre Fischer{ 11151108b05eSAndre Fischer my ($release_descriptor) = @_; 1116f219747dSAndre Fischer 1117f219747dSAndre Fischer my @download_sets = (); 1118f219747dSAndre Fischer 11191108b05eSAndre Fischer foreach my $platform_descriptor (values %{$release_descriptor->{'platforms'}}) 1120f219747dSAndre Fischer { 11219dd622cdSAndre Fischer my $platform_path = sprintf("%s/instsetoo_native/%s", 11229dd622cdSAndre Fischer $ENV{'SOLARSRC'}, 11239dd622cdSAndre Fischer $platform_descriptor->{'id'}); 11249dd622cdSAndre Fischer if ( ! -d $platform_path) 11259dd622cdSAndre Fischer { 11269dd622cdSAndre Fischer printf "ignoring missing %s\n", $platform_path; 11279dd622cdSAndre Fischer next; 11289dd622cdSAndre Fischer } 11291108b05eSAndre Fischer for my $package_descriptor (values %{$release_descriptor->{'packages'}}) 1130f219747dSAndre Fischer { 11311108b05eSAndre Fischer my $platform_package_descriptor = GetPlatformPackage( 11321108b05eSAndre Fischer $release_descriptor, 11331108b05eSAndre Fischer $platform_descriptor, 11341108b05eSAndre Fischer $package_descriptor); 11359dd622cdSAndre Fischer my @package_formats = @{$platform_descriptor->{'package-types'}}; 11369dd622cdSAndre Fischer for my $package_format (@package_formats) 1137f219747dSAndre Fischer { 11381108b05eSAndre Fischer for my $language_id (@{$release_descriptor->{'language-ids'}}) 1139f219747dSAndre Fischer { 11401108b05eSAndre Fischer my ($archive_path, $archive_name) = GetInstallationPackageName( 11411108b05eSAndre Fischer $release_descriptor, 11421108b05eSAndre Fischer $platform_package_descriptor, 11439dd622cdSAndre Fischer $package_format, 11449dd622cdSAndre Fischer $language_id); 11451108b05eSAndre Fischer my $candidate = $archive_path."/".$archive_name; 11469dd622cdSAndre Fischer if ( ! -f $candidate) 11479dd622cdSAndre Fischer { 11489dd622cdSAndre Fischer# printf STDERR "ERROR: can not find download set '%s'\n", $candidate; 11499dd622cdSAndre Fischer next; 11509dd622cdSAndre Fischer } 11519dd622cdSAndre Fischer printf "adding %s\n", $archive_name; 11521108b05eSAndre Fischer my $download_set = { 11531108b05eSAndre Fischer 'source-path' => $archive_path, 11549dd622cdSAndre Fischer 'archive-name' => $archive_name, 11551108b05eSAndre Fischer 'platform' => $platform_descriptor->{'archive-platform'}, 11569dd622cdSAndre Fischer 'destination-path' => sprintf("developer-snapshots/%s/%s", 11571108b05eSAndre Fischer $release_descriptor->{'name'}, 11581108b05eSAndre Fischer $platform_descriptor->{'archive-platform'}) 11599dd622cdSAndre Fischer }; 11601108b05eSAndre Fischer printf " %s\n", $download_set->{'destination-path'}; 11611108b05eSAndre Fischer push @download_sets, $download_set; 1162f219747dSAndre Fischer } 1163f219747dSAndre Fischer } 1164f219747dSAndre Fischer } 1165f219747dSAndre Fischer } 1166f219747dSAndre Fischer 1167f219747dSAndre Fischer return @download_sets; 1168f219747dSAndre Fischer} 1169f219747dSAndre Fischer 1170f219747dSAndre Fischer 1171f219747dSAndre Fischer 1172f219747dSAndre Fischer 11739dd622cdSAndre Fischer=head2 ProvideChecksums ($context, @download_sets) 11749dd622cdSAndre Fischer 11759dd622cdSAndre Fischer Create checksums in MD5 and SHA256 format and a gpg signature for the given download set. 11769dd622cdSAndre Fischer The checksums are not created when they already exists and are not older than the download set. 11779dd622cdSAndre Fischer 11789dd622cdSAndre Fischer=cut 11799dd622cdSAndre Fischersub ProvideChecksums ($@) 1180f219747dSAndre Fischer{ 11819dd622cdSAndre Fischer my ($context, @download_sets) = @_; 11829dd622cdSAndre Fischer 11839dd622cdSAndre Fischer my @asc_requests = (); 11849dd622cdSAndre Fischer foreach my $download_set (@download_sets) 11859dd622cdSAndre Fischer { 11869dd622cdSAndre Fischer printf "%s\n", $download_set->{'archive-name'}; 11879dd622cdSAndre Fischer my $full_archive_name = $download_set->{'source-path'} . "/" . $download_set->{'archive-name'}; 11889dd622cdSAndre Fischer $full_archive_name = Trim(qx(cygpath -u "$full_archive_name")); 1189f219747dSAndre Fischer 11909dd622cdSAndre Fischer my $md5_filename = $full_archive_name . ".md5"; 11919dd622cdSAndre Fischer if ( ! -f $md5_filename || IsOlderThan($md5_filename, $full_archive_name)) 11929dd622cdSAndre Fischer { 11939dd622cdSAndre Fischer if ($context->{'dry-run'}) 11949dd622cdSAndre Fischer { 11959dd622cdSAndre Fischer printf " would create MD5\n"; 11969dd622cdSAndre Fischer } 11979dd622cdSAndre Fischer else 11989dd622cdSAndre Fischer { 11999dd622cdSAndre Fischer my $digest = Digest::MD5->new(); 12001108b05eSAndre Fischer open my ($in), $full_archive_name; 12019dd622cdSAndre Fischer $digest->addfile($in); 12029dd622cdSAndre Fischer my $checksum = $digest->hexdigest(); 12039dd622cdSAndre Fischer close $in; 1204f219747dSAndre Fischer 12051108b05eSAndre Fischer open my ($out), ">", $md5_filename; 12069dd622cdSAndre Fischer printf $out "%s *%s", $checksum, $download_set->{'archive-name'}; 12079dd622cdSAndre Fischer close $out; 1208f219747dSAndre Fischer 12099dd622cdSAndre Fischer printf " created MD5\n"; 12109dd622cdSAndre Fischer } 12119dd622cdSAndre Fischer } 12129dd622cdSAndre Fischer else 12139dd622cdSAndre Fischer { 12149dd622cdSAndre Fischer printf " MD5 already exists\n"; 12159dd622cdSAndre Fischer } 1216f219747dSAndre Fischer 12179dd622cdSAndre Fischer my $sha256_filename = $full_archive_name . ".sha256"; 12189dd622cdSAndre Fischer if ( ! -f $sha256_filename || IsOlderThan($sha256_filename, $full_archive_name)) 12199dd622cdSAndre Fischer { 12209dd622cdSAndre Fischer if ($context->{'dry-run'}) 12219dd622cdSAndre Fischer { 12229dd622cdSAndre Fischer printf " would create SHA256\n"; 12239dd622cdSAndre Fischer } 12249dd622cdSAndre Fischer else 12259dd622cdSAndre Fischer { 12269dd622cdSAndre Fischer my $digest = Digest::SHA->new("sha256"); 12271108b05eSAndre Fischer open my ($in), $full_archive_name; 12289dd622cdSAndre Fischer $digest->addfile($in); 12299dd622cdSAndre Fischer my $checksum = $digest->hexdigest(); 12309dd622cdSAndre Fischer close $in; 1231f219747dSAndre Fischer 12321108b05eSAndre Fischer open my ($out), ">", $sha256_filename; 12339dd622cdSAndre Fischer printf $out "%s *%s", $checksum, $download_set->{'archive-name'}; 12349dd622cdSAndre Fischer close $out; 1235f219747dSAndre Fischer 12369dd622cdSAndre Fischer printf " created SHA256\n"; 12379dd622cdSAndre Fischer } 12389dd622cdSAndre Fischer } 12399dd622cdSAndre Fischer else 12409dd622cdSAndre Fischer { 12419dd622cdSAndre Fischer printf " SHA256 already exists\n"; 12429dd622cdSAndre Fischer } 1243f219747dSAndre Fischer 12449dd622cdSAndre Fischer my $asc_filename = $full_archive_name . ".asc"; 12459dd622cdSAndre Fischer if ( ! -f $asc_filename || IsOlderThan($asc_filename, $full_archive_name)) 12469dd622cdSAndre Fischer { 12479dd622cdSAndre Fischer if ($context->{'dry-run'}) 12489dd622cdSAndre Fischer { 12499dd622cdSAndre Fischer printf " would create ASC\n"; 12509dd622cdSAndre Fischer } 12519dd622cdSAndre Fischer else 12529dd622cdSAndre Fischer { 12539dd622cdSAndre Fischer # gpg seems not to be able to sign more than one file at a time. 12549dd622cdSAndre Fischer # Password has to be provided every time. 12559dd622cdSAndre Fischer my $command = sprintf("gpg --armor --detach-sig \"%s\"", $full_archive_name); 12569dd622cdSAndre Fischer print $command; 12579dd622cdSAndre Fischer my $result = system($command); 12589dd622cdSAndre Fischer printf " created ASC\n"; 12599dd622cdSAndre Fischer } 12609dd622cdSAndre Fischer } 12619dd622cdSAndre Fischer else 12629dd622cdSAndre Fischer { 12639dd622cdSAndre Fischer printf " ASC already exists\n"; 12649dd622cdSAndre Fischer } 1265f219747dSAndre Fischer } 1266f219747dSAndre Fischer} 1267f219747dSAndre Fischer 1268f219747dSAndre Fischer 1269f219747dSAndre Fischer 1270f219747dSAndre Fischer 12719dd622cdSAndre Fischer=head2 IsOlderThan ($filename1, $filename2) 12729dd622cdSAndre Fischer 12739dd622cdSAndre Fischer Return true (1) if the last modification date of $filename1 is older than (<) that of $filename2. 12749dd622cdSAndre Fischer 12759dd622cdSAndre Fischer=cut 12769dd622cdSAndre Fischersub IsOlderThan ($$) 1277f219747dSAndre Fischer{ 12789dd622cdSAndre Fischer my ($filename1, $filename2) = @_; 12799dd622cdSAndre Fischer 12809dd622cdSAndre Fischer my @stat1 = stat $filename1; 12819dd622cdSAndre Fischer my @stat2 = stat $filename2; 12829dd622cdSAndre Fischer 12839dd622cdSAndre Fischer return $stat1[9] < $stat2[9]; 1284f219747dSAndre Fischer} 1285f219747dSAndre Fischer 1286f219747dSAndre Fischer 1287f219747dSAndre Fischer 1288f219747dSAndre Fischer 12891108b05eSAndre Fischersub GetInstallationPackageName ($$$$) 1290f219747dSAndre Fischer{ 12911108b05eSAndre Fischer my ($release_descriptor, $platform_package_descriptor, $package_format, $language) = @_; 12929dd622cdSAndre Fischer 12931108b05eSAndre Fischer my $path = ResolveTemplate( 12941108b05eSAndre Fischer $platform_package_descriptor->{'archive-path'}, 12951108b05eSAndre Fischer $release_descriptor, 12961108b05eSAndre Fischer $platform_package_descriptor, 12971108b05eSAndre Fischer $package_format, 12981108b05eSAndre Fischer $language); 12991108b05eSAndre Fischer my $name = ResolveTemplate( 13001108b05eSAndre Fischer $platform_package_descriptor->{'archive-name'}, 13011108b05eSAndre Fischer $release_descriptor, 13021108b05eSAndre Fischer $platform_package_descriptor, 13031108b05eSAndre Fischer $package_format, 13041108b05eSAndre Fischer $language); 13059dd622cdSAndre Fischer 13061108b05eSAndre Fischer return ($path, $name); 13079dd622cdSAndre Fischer} 13089dd622cdSAndre Fischer 13099dd622cdSAndre Fischer 13109dd622cdSAndre Fischer 13119dd622cdSAndre Fischer 13121108b05eSAndre Fischersub ResolveTemplate ($$$$$) 13139dd622cdSAndre Fischer{ 13141108b05eSAndre Fischer my ($template, $release_descriptor, $platform_package_descriptor, $package_format, $language) = @_; 13151108b05eSAndre Fischer 13161108b05eSAndre Fischer my $archive_package_type = ""; 13171108b05eSAndre Fischer if ($platform_package_descriptor->{'add-package-type-to-archive-name'} =~ /^(1|true|yes)$/i) 13181108b05eSAndre Fischer { 13191108b05eSAndre Fischer $archive_package_type = "-".$package_format; 13201108b05eSAndre Fischer } 13219dd622cdSAndre Fischer my $full_language = $language; 13229dd622cdSAndre Fischer if ($EnUSBasedLanguages{$language}) 1323f219747dSAndre Fischer { 13249dd622cdSAndre Fischer $full_language = "en-US_".$language; 1325f219747dSAndre Fischer } 13261108b05eSAndre Fischer my $extension = $platform_package_descriptor->{'download-extension'}; 13271108b05eSAndre Fischer if ( ! defined $extension) 13281108b05eSAndre Fischer { 13291108b05eSAndre Fischer $extension = $platform_package_descriptor->{'extension'}; 13301108b05eSAndre Fischer } 13311108b05eSAndre Fischer 13321108b05eSAndre Fischer my $old_to_new_version_dash = sprintf( 13331108b05eSAndre Fischer "v-%s_v-%s", 13341108b05eSAndre Fischer $release_descriptor->{'previous-version'}, 13351108b05eSAndre Fischer $release_descriptor->{'version'}); 13361108b05eSAndre Fischer $old_to_new_version_dash =~ s/\./-/g; 13371108b05eSAndre Fischer my $old_to_new_version_dots = sprintf( 13381108b05eSAndre Fischer "%s-%s", 13391108b05eSAndre Fischer $release_descriptor->{'previous-version'}, 13401108b05eSAndre Fischer $release_descriptor->{'version'}); 13419dd622cdSAndre Fischer 13421108b05eSAndre Fischer 13431108b05eSAndre Fischer my $name = $template; 13441108b05eSAndre Fischer 134586e1cf34SPedro Giffuni # Resolve %? template parameters. 13461108b05eSAndre Fischer $name =~ s/%V/$release_descriptor->{'version'}/g; 13471108b05eSAndre Fischer $name =~ s/%W/$old_to_new_version_dash/g; 13481108b05eSAndre Fischer $name =~ s/%w/$old_to_new_version_dots/g; 13491108b05eSAndre Fischer $name =~ s/%P/$platform_package_descriptor->{'archive-platform'}/g; 13501108b05eSAndre Fischer $name =~ s/%t/$archive_package_type/g; 13511108b05eSAndre Fischer $name =~ s/%T/$package_format/g; 13521108b05eSAndre Fischer $name =~ s/%l/$full_language/g; 13531108b05eSAndre Fischer $name =~ s/%L/$language/g; 13541108b05eSAndre Fischer $name =~ s/%E/$extension/g; 13551108b05eSAndre Fischer 13561108b05eSAndre Fischer # Resolve $name environment references. 13571108b05eSAndre Fischer while ($name =~ /^(.*?)\$([a-zA-Z0-9_]+)(.*)$/) 13581108b05eSAndre Fischer { 13591108b05eSAndre Fischer $name = $1 . $ENV{$2} . $3; 13601108b05eSAndre Fischer } 13611108b05eSAndre Fischer 13621108b05eSAndre Fischer return $name; 1363f219747dSAndre Fischer} 1364f219747dSAndre Fischer 1365f219747dSAndre Fischer 1366f219747dSAndre Fischer 1367f219747dSAndre Fischer 13689dd622cdSAndre Fischersub GetCurrentPlatformDescriptor ($) 1369f219747dSAndre Fischer{ 13701108b05eSAndre Fischer my ($release_descriptor) = @_; 13719dd622cdSAndre Fischer 13721108b05eSAndre Fischer my $platform_descriptor = $release_descriptor->{'platforms'}->{$ENV{'INPATH'}}; 13739dd622cdSAndre Fischer if ( ! defined $platform_descriptor) 1374f219747dSAndre Fischer { 13759dd622cdSAndre Fischer printf STDERR "ERROR: platform '%s' is not supported\n", $ENV{'INPATH'}; 1376f219747dSAndre Fischer } 13779dd622cdSAndre Fischer return $platform_descriptor; 1378f219747dSAndre Fischer} 1379f219747dSAndre Fischer 1380f219747dSAndre Fischer 1381f219747dSAndre Fischer 1382f219747dSAndre Fischer 13831108b05eSAndre Fischersub GetPlatformPackage ($$$) 13841108b05eSAndre Fischer{ 13851108b05eSAndre Fischer my ($release_descriptor, $platform_descriptor, $package_descriptor) = @_; 13861108b05eSAndre Fischer my $key = sprintf("%s/%s", $platform_descriptor->{'id'}, $package_descriptor->{'id'}); 13871108b05eSAndre Fischer 13881108b05eSAndre Fischer my $platform_package = $release_descriptor->{'platform-packages'}->{$key}; 13891108b05eSAndre Fischer $platform_package = {} 13901108b05eSAndre Fischer unless defined $platform_package; 13911108b05eSAndre Fischer 13921108b05eSAndre Fischer my $joined_descriptor = { 13931108b05eSAndre Fischer %$platform_descriptor, 13941108b05eSAndre Fischer %$package_descriptor, 13951108b05eSAndre Fischer %$platform_package, 13961108b05eSAndre Fischer 'id' => $key, 13971108b05eSAndre Fischer 'platform-id' => $platform_descriptor->{'id'}, 13981108b05eSAndre Fischer 'package-id' => $package_descriptor->{'id'} 13991108b05eSAndre Fischer }; 14001108b05eSAndre Fischer return $joined_descriptor; 14011108b05eSAndre Fischer} 14021108b05eSAndre Fischer 14031108b05eSAndre Fischer 14041108b05eSAndre Fischer 14051108b05eSAndre Fischer 1406f219747dSAndre Fischersub Wiki ($$) 1407f219747dSAndre Fischer{ 1408f219747dSAndre Fischer my ($release_descriptor, $context) = @_; 1409f219747dSAndre Fischer 1410f219747dSAndre Fischer open my $out, ">", $context->{'output-filename'}; 1411f219747dSAndre Fischer 1412f219747dSAndre Fischer my @table_list = GetTableList($release_descriptor); 1413f219747dSAndre Fischer foreach my $table_name (@table_list) 1414f219747dSAndre Fischer { 1415f219747dSAndre Fischer my @table_packages = GetPackagesForTable($release_descriptor, $table_name); 1416f219747dSAndre Fischer my @table_languages = GetLanguagesForTable($release_descriptor, @table_packages); 1417f219747dSAndre Fischer my @table_platforms = GetPlatformsForTable($release_descriptor, @table_packages); 1418f219747dSAndre Fischer 14199dd622cdSAndre Fischer printf "packages: %s\n", join(", ", map {$_->{'package'}->{'display-name'}} @table_packages); 1420f219747dSAndre Fischer printf "languages: %s\n", join(", ", map {$_->{'english-name'}} @table_languages); 1421f219747dSAndre Fischer printf "platforms: %s\n", join(", ", map {$_->{'id'}} @table_platforms); 1422f219747dSAndre Fischer 1423f219747dSAndre Fischer print $out "{| class=\"wikitable\"\n"; 14249dd622cdSAndre Fischer 14259dd622cdSAndre Fischer # Write the table head. 1426f219747dSAndre Fischer print $out "|-\n"; 1427f219747dSAndre Fischer print $out "! colspan=\"2\" | Language<br>The names do not refer to countries\n"; 1428f219747dSAndre Fischer print $out "! Type\n"; 1429f219747dSAndre Fischer foreach my $platform_descriptor (@table_platforms) 1430f219747dSAndre Fischer { 14319dd622cdSAndre Fischer foreach my $package_type (@{$platform_descriptor->{'package-types'}}) 14329dd622cdSAndre Fischer { 14339dd622cdSAndre Fischer printf $out "! %s<br>%s bit<br>%s\n", 1434f219747dSAndre Fischer $platform_descriptor->{'display-name'}, 1435f219747dSAndre Fischer $platform_descriptor->{'word-size'}, 14369dd622cdSAndre Fischer uc($package_type); 14379dd622cdSAndre Fischer } 1438f219747dSAndre Fischer } 1439f219747dSAndre Fischer 1440f219747dSAndre Fischer foreach my $language_descriptor (@table_languages) 1441f219747dSAndre Fischer { 1442f219747dSAndre Fischer if ($context->{'check-links'}) 1443f219747dSAndre Fischer { 1444f219747dSAndre Fischer $| = 1; 14451108b05eSAndre Fischer printf "%-5s: ", $language_descriptor->{'id'}; 1446f219747dSAndre Fischer } 1447f219747dSAndre Fischer 1448f219747dSAndre Fischer print $out "|-\n"; 1449f219747dSAndre Fischer printf $out "| rowspan=\"%d\" | %s\n", scalar @table_packages, $language_descriptor->{'english-name'}; 1450f219747dSAndre Fischer printf $out "| rowspan=\"%d\" | %s\n", scalar @table_packages, $language_descriptor->{'local-name'}; 1451f219747dSAndre Fischer 1452f219747dSAndre Fischer my $is_first = 1; 14539dd622cdSAndre Fischer foreach my $wiki_package_descriptor (@table_packages) 1454f219747dSAndre Fischer { 14559dd622cdSAndre Fischer my $package_descriptor = $wiki_package_descriptor->{'package'}; 14569dd622cdSAndre Fischer 1457f219747dSAndre Fischer if ($is_first) 1458f219747dSAndre Fischer { 1459f219747dSAndre Fischer $is_first = 0; 1460f219747dSAndre Fischer } 1461f219747dSAndre Fischer else 1462f219747dSAndre Fischer { 1463f219747dSAndre Fischer printf $out "|-\n"; 1464f219747dSAndre Fischer } 1465f219747dSAndre Fischer 1466f219747dSAndre Fischer # Write the name of the package, e.g. Full Install or Langpack. 1467f219747dSAndre Fischer if (defined $package_descriptor->{'link-URL'}) 1468f219747dSAndre Fischer { 1469f219747dSAndre Fischer printf $out "| [%s %s]\n", 1470f219747dSAndre Fischer $package_descriptor->{'link-URL'}, 1471f219747dSAndre Fischer $package_descriptor->{'display-name'}; 1472f219747dSAndre Fischer } 1473f219747dSAndre Fischer else 1474f219747dSAndre Fischer { 1475f219747dSAndre Fischer printf $out "| %s\n", $package_descriptor->{'display-name'}; 1476f219747dSAndre Fischer } 1477f219747dSAndre Fischer 1478f219747dSAndre Fischer foreach my $platform_descriptor (@table_platforms) 1479f219747dSAndre Fischer { 14801108b05eSAndre Fischer my $platform_package_descriptor = GetPlatformPackage( 14811108b05eSAndre Fischer $release_descriptor, 14821108b05eSAndre Fischer $platform_descriptor, 14831108b05eSAndre Fischer $package_descriptor); 14841108b05eSAndre Fischer 14851108b05eSAndre Fischer foreach my $package_type (@{$platform_package_descriptor->{'package-types'}}) 14869dd622cdSAndre Fischer { 14879dd622cdSAndre Fischer WriteDownloadLinks( 14889dd622cdSAndre Fischer $out, 14899dd622cdSAndre Fischer $release_descriptor, 14909dd622cdSAndre Fischer $context, 14919dd622cdSAndre Fischer $language_descriptor, 14929dd622cdSAndre Fischer $wiki_package_descriptor, 14931108b05eSAndre Fischer $platform_package_descriptor, 14949dd622cdSAndre Fischer $package_type); 14959dd622cdSAndre Fischer } 1496f219747dSAndre Fischer } 1497f219747dSAndre Fischer } 1498f219747dSAndre Fischer 1499f219747dSAndre Fischer if ($context->{'check-links'}) 1500f219747dSAndre Fischer { 1501f219747dSAndre Fischer printf "\n"; 1502f219747dSAndre Fischer } 1503f219747dSAndre Fischer } 1504f219747dSAndre Fischer 1505f219747dSAndre Fischer print $out "|}\n"; 1506f219747dSAndre Fischer } 1507f219747dSAndre Fischer close $out; 1508f219747dSAndre Fischer} 1509f219747dSAndre Fischer 1510f219747dSAndre Fischer 1511f219747dSAndre Fischer 1512f219747dSAndre Fischer 1513f219747dSAndre Fischersub GetTableList ($) 1514f219747dSAndre Fischer{ 1515f219747dSAndre Fischer my ($release_descriptor) = @_; 1516f219747dSAndre Fischer 1517f219747dSAndre Fischer my %seen_table_names = (); 1518f219747dSAndre Fischer my @table_names = (); 15199dd622cdSAndre Fischer foreach my $wiki_package_descriptor (@{$release_descriptor->{'wiki-packages'}}) 1520f219747dSAndre Fischer { 15219dd622cdSAndre Fischer my $table_name = $wiki_package_descriptor->{'table'}; 1522f219747dSAndre Fischer if ( ! $seen_table_names{$table_name}) 1523f219747dSAndre Fischer { 1524f219747dSAndre Fischer push @table_names, $table_name; 1525f219747dSAndre Fischer $seen_table_names{$table_name} = 1; 1526f219747dSAndre Fischer } 1527f219747dSAndre Fischer } 1528f219747dSAndre Fischer return @table_names; 1529f219747dSAndre Fischer} 1530f219747dSAndre Fischer 1531f219747dSAndre Fischer 1532f219747dSAndre Fischer 1533f219747dSAndre Fischer 1534f219747dSAndre Fischersub GetPackagesForTable ($$) 1535f219747dSAndre Fischer{ 1536f219747dSAndre Fischer my ($release_descriptor, $table_name) = @_; 1537f219747dSAndre Fischer 1538f219747dSAndre Fischer my @packages = (); 15399dd622cdSAndre Fischer foreach my $wiki_package_descriptor (@{$release_descriptor->{'wiki-packages'}}) 1540f219747dSAndre Fischer { 15419dd622cdSAndre Fischer if ($wiki_package_descriptor->{'table'} eq $table_name) 1542f219747dSAndre Fischer { 15439dd622cdSAndre Fischer my $package_descriptor = $release_descriptor->{'packages'}->{ 15449dd622cdSAndre Fischer $wiki_package_descriptor->{'package-id'}}; 15459dd622cdSAndre Fischer $wiki_package_descriptor->{'package'} = $package_descriptor; 15469dd622cdSAndre Fischer push @packages, $wiki_package_descriptor; 1547f219747dSAndre Fischer } 1548f219747dSAndre Fischer } 1549f219747dSAndre Fischer return @packages; 1550f219747dSAndre Fischer} 1551f219747dSAndre Fischer 1552f219747dSAndre Fischer 1553f219747dSAndre Fischer 1554f219747dSAndre Fischer 1555f219747dSAndre Fischersub GetLanguagesForTable ($@) 1556f219747dSAndre Fischer{ 1557f219747dSAndre Fischer my ($release_descriptor, @packages) = @_; 1558f219747dSAndre Fischer 1559f219747dSAndre Fischer # Find the languages that are reference by at least one package. 1560f219747dSAndre Fischer my %matching_languages = (); 1561f219747dSAndre Fischer foreach my $package_descriptor (@packages) 1562f219747dSAndre Fischer { 1563f219747dSAndre Fischer foreach my $language_id (@{$package_descriptor->{'language-list'}}) 1564f219747dSAndre Fischer { 1565f219747dSAndre Fischer $matching_languages{$language_id} = 1; 1566f219747dSAndre Fischer } 1567f219747dSAndre Fischer } 1568f219747dSAndre Fischer 1569f219747dSAndre Fischer # Retrieve the language descriptors for the language ids. 1570f219747dSAndre Fischer my @matching_language_descriptors = (); 1571f219747dSAndre Fischer foreach my $language_id (@{$release_descriptor->{'language-ids'}}) 1572f219747dSAndre Fischer { 1573f219747dSAndre Fischer if (defined $matching_languages{$language_id}) 1574f219747dSAndre Fischer { 1575f219747dSAndre Fischer my $language_descriptor = $release_descriptor->{'languages'}->{$language_id}; 1576f219747dSAndre Fischer if (defined $language_descriptor) 1577f219747dSAndre Fischer { 1578f219747dSAndre Fischer push @matching_language_descriptors, $language_descriptor; 1579f219747dSAndre Fischer } 1580f219747dSAndre Fischer } 1581f219747dSAndre Fischer } 1582f219747dSAndre Fischer 1583f219747dSAndre Fischer return @matching_language_descriptors; 1584f219747dSAndre Fischer} 1585f219747dSAndre Fischer 1586f219747dSAndre Fischer 1587f219747dSAndre Fischer 1588f219747dSAndre Fischer 1589f219747dSAndre Fischersub GetPlatformsForTable ($@) 1590f219747dSAndre Fischer{ 1591f219747dSAndre Fischer my ($release_descriptor, @packages) = @_; 1592f219747dSAndre Fischer 1593f219747dSAndre Fischer # Find the platforms that are reference by at least one package. 1594f219747dSAndre Fischer my %matching_platform_ids = (); 1595f219747dSAndre Fischer foreach my $package_descriptor (@packages) 1596f219747dSAndre Fischer { 1597f219747dSAndre Fischer foreach my $platform_id (@{$package_descriptor->{'platform-list'}}) 1598f219747dSAndre Fischer { 1599f219747dSAndre Fischer $matching_platform_ids{$platform_id} = 1; 1600f219747dSAndre Fischer } 1601f219747dSAndre Fischer } 1602f219747dSAndre Fischer 1603f219747dSAndre Fischer # Retrieve the platform descriptors for the plaform ids. 1604f219747dSAndre Fischer my @matching_platform_descriptors = (); 1605f219747dSAndre Fischer foreach my $platform_id (@{$release_descriptor->{'platform-ids'}}) 1606f219747dSAndre Fischer { 1607f219747dSAndre Fischer if ($matching_platform_ids{$platform_id}) 1608f219747dSAndre Fischer { 16099dd622cdSAndre Fischer print $platform_id."\n"; 1610f219747dSAndre Fischer push @matching_platform_descriptors, $release_descriptor->{'platforms'}->{$platform_id}; 1611f219747dSAndre Fischer } 1612f219747dSAndre Fischer } 1613f219747dSAndre Fischer 1614f219747dSAndre Fischer return @matching_platform_descriptors; 1615f219747dSAndre Fischer} 1616f219747dSAndre Fischer 1617f219747dSAndre Fischer 1618f219747dSAndre Fischer 1619f219747dSAndre Fischer 1620f219747dSAndre Fischermy $bold_text_start = "<b>"; 1621f219747dSAndre Fischermy $bold_text_end = "</b>"; 1622f219747dSAndre Fischermy $small_text_start = "<span style=\"font-size:80%\">"; 1623f219747dSAndre Fischermy $small_text_end = "</span>"; 1624f219747dSAndre Fischermy $broken_link_start = "<span style=\"color:#FF0000\">"; 1625f219747dSAndre Fischermy $broken_link_end = "</span>"; 1626f219747dSAndre Fischer 1627f219747dSAndre Fischer 16289dd622cdSAndre Fischersub WriteDownloadLinks ($$$$$$$) 1629f219747dSAndre Fischer{ 1630f219747dSAndre Fischer my ($out, 16319dd622cdSAndre Fischer $release_descriptor, 1632f219747dSAndre Fischer $context, 1633f219747dSAndre Fischer $language_descriptor, 16349dd622cdSAndre Fischer $wiki_package_descriptor, 16351108b05eSAndre Fischer $platform_package_descriptor, 16369dd622cdSAndre Fischer $package_type) = @_; 16379dd622cdSAndre Fischer 1638f219747dSAndre Fischer # Check if the current language and platform match the package. 16391108b05eSAndre Fischer my $platform_id = $platform_package_descriptor->{'platform-id'}; 16401108b05eSAndre Fischer if (defined $wiki_package_descriptor->{'platforms'}->{$platform_id} 16419dd622cdSAndre Fischer && defined $wiki_package_descriptor->{'languages'}->{$language_descriptor->{'id'}}) 1642f219747dSAndre Fischer { 1643f219747dSAndre Fischer my $archive_package_name = ""; 1644f219747dSAndre Fischer my $extension = $package_type; 16451108b05eSAndre Fischer if (defined $platform_package_descriptor->{'extension'}) 1646f219747dSAndre Fischer { 16471108b05eSAndre Fischer $extension = $platform_package_descriptor->{'extension'}; 1648f219747dSAndre Fischer } 16491108b05eSAndre Fischer if (defined $platform_package_descriptor->{'download-extension'}) 1650f219747dSAndre Fischer { 16511108b05eSAndre Fischer $extension = $platform_package_descriptor->{'download-extension'}; 1652f219747dSAndre Fischer } 1653f219747dSAndre Fischer $archive_package_name = "-".$package_type if ($package_type =~ /deb|rpm/); 16549dd622cdSAndre Fischer 16551108b05eSAndre Fischer my ($archive_path, $archive_name) = GetInstallationPackageName( 16569dd622cdSAndre Fischer $release_descriptor, 16571108b05eSAndre Fischer $platform_package_descriptor, 16589dd622cdSAndre Fischer $package_type, 16599dd622cdSAndre Fischer $language_descriptor->{'id'}); 16609dd622cdSAndre Fischer 16619dd622cdSAndre Fischer printf $out "| align=\"center\" | "; 16629dd622cdSAndre Fischer my $download = FindDownload( 16639dd622cdSAndre Fischer $context, 16649dd622cdSAndre Fischer $release_descriptor, 16651108b05eSAndre Fischer $platform_package_descriptor, 16669dd622cdSAndre Fischer $package_type, 16679dd622cdSAndre Fischer $archive_name); 16689dd622cdSAndre Fischer if (defined $download) 16699dd622cdSAndre Fischer { 16709dd622cdSAndre Fischer my $url = $download->{'base-url'} . "/". $archive_name; 16719dd622cdSAndre Fischer printf $out "%s%s%s<br><br>%s%s %s<br>%s%s", 1672f219747dSAndre Fischer $bold_text_start, 1673f219747dSAndre Fischer CreateLink($url, $extension, $context), 1674f219747dSAndre Fischer $bold_text_end, 1675f219747dSAndre Fischer $small_text_start, 1676f219747dSAndre Fischer CreateLink($url.".asc", "ASC", $context), 1677f219747dSAndre Fischer CreateLink($url.".md5", "MD5", $context), 1678f219747dSAndre Fischer CreateLink($url.".sha256", "SHA256", $context), 1679f219747dSAndre Fischer $small_text_end; 16809dd622cdSAndre Fischer } 16819dd622cdSAndre Fischer printf $out "\n"; 1682f219747dSAndre Fischer } 1683f219747dSAndre Fischer else 1684f219747dSAndre Fischer { 1685f219747dSAndre Fischer printf $out "|\n"; 1686f219747dSAndre Fischer } 1687f219747dSAndre Fischer} 1688f219747dSAndre Fischer 1689f219747dSAndre Fischer 1690f219747dSAndre Fischer 1691f219747dSAndre Fischer 16929dd622cdSAndre Fischersub FindDownload ($$$$$) 16939dd622cdSAndre Fischer{ 16949dd622cdSAndre Fischer my ($context, 16951108b05eSAndre Fischer $release_descriptor, 16961108b05eSAndre Fischer $platform_package_descriptor, 16971108b05eSAndre Fischer $package_type, 16989dd622cdSAndre Fischer $archive_name) = @_; 16999dd622cdSAndre Fischer 17009dd622cdSAndre Fischer foreach my $download (@{$release_descriptor->{'downloads'}}) 17019dd622cdSAndre Fischer { 17021108b05eSAndre Fischer if ($download->{'platform-id'} eq $platform_package_descriptor->{'platform-id'}) 17039dd622cdSAndre Fischer { 17049dd622cdSAndre Fischer my $url = $download->{'base-url'} . "/". $archive_name; 17059dd622cdSAndre Fischer if ($context->{'check-links'}) 17069dd622cdSAndre Fischer { 17079dd622cdSAndre Fischer if (CheckLink($url)) 17089dd622cdSAndre Fischer { 17099dd622cdSAndre Fischer # URL points to an existing file. 17109dd622cdSAndre Fischer printf "+"; 17119dd622cdSAndre Fischer return $download; 17129dd622cdSAndre Fischer } 17139dd622cdSAndre Fischer else 17149dd622cdSAndre Fischer { 17159dd622cdSAndre Fischer # URL is broken. 17169dd622cdSAndre Fischer # Try the next download area for the platform. 17179dd622cdSAndre Fischer next; 17189dd622cdSAndre Fischer } 17199dd622cdSAndre Fischer } 17209dd622cdSAndre Fischer else 17219dd622cdSAndre Fischer { 17229dd622cdSAndre Fischer # Use the URL unchecked. If there is more than one download area for the platform then only 17239dd622cdSAndre Fischer # the first is ever used. 17249dd622cdSAndre Fischer printf "."; 17259dd622cdSAndre Fischer return $download; 17269dd622cdSAndre Fischer } 17279dd622cdSAndre Fischer } 17289dd622cdSAndre Fischer } 17299dd622cdSAndre Fischer 17309dd622cdSAndre Fischer if ($context->{'check-links'}) 17319dd622cdSAndre Fischer { 17329dd622cdSAndre Fischer printf "-"; 17339dd622cdSAndre Fischer } 17349dd622cdSAndre Fischer 17359dd622cdSAndre Fischer return undef; 17369dd622cdSAndre Fischer} 17379dd622cdSAndre Fischer 17389dd622cdSAndre Fischer 17399dd622cdSAndre Fischer 17409dd622cdSAndre Fischer 1741f219747dSAndre Fischersub CreateLink ($$$) 1742f219747dSAndre Fischer{ 1743f219747dSAndre Fischer my ($url, $text, $context) = @_; 1744f219747dSAndre Fischer 1745f219747dSAndre Fischer my $is_link_broken = 0; 1746f219747dSAndre Fischer if ($context->{'check-links'}) 1747f219747dSAndre Fischer { 17489dd622cdSAndre Fischer if (CheckLink($url)) 17499dd622cdSAndre Fischer { 17509dd622cdSAndre Fischer $is_link_broken = 0; 17519dd622cdSAndre Fischer printf "+"; 17529dd622cdSAndre Fischer } 17539dd622cdSAndre Fischer else 17549dd622cdSAndre Fischer { 17559dd622cdSAndre Fischer $is_link_broken = 1; 17569dd622cdSAndre Fischer printf "-"; 17579dd622cdSAndre Fischer } 17589dd622cdSAndre Fischer } 17599dd622cdSAndre Fischer else 17609dd622cdSAndre Fischer { 1761f219747dSAndre Fischer printf "."; 1762f219747dSAndre Fischer } 1763f219747dSAndre Fischer 1764f219747dSAndre Fischer if ( ! $is_link_broken) 1765f219747dSAndre Fischer { 1766f219747dSAndre Fischer return sprintf ("[%s %s]", $url, $text); 1767f219747dSAndre Fischer } 1768f219747dSAndre Fischer elsif ($context->{'mark-broken-links'}) 1769f219747dSAndre Fischer { 1770f219747dSAndre Fischer return sprintf ("%sbroken%s[%s %s]", $broken_link_start, $broken_link_end, $url, $text); 1771f219747dSAndre Fischer } 1772f219747dSAndre Fischer else 1773f219747dSAndre Fischer { 1774f219747dSAndre Fischer return sprintf ("%s", $text); 1775f219747dSAndre Fischer } 1776f219747dSAndre Fischer} 1777f219747dSAndre Fischer 1778f219747dSAndre Fischer 1779f219747dSAndre Fischer 1780f219747dSAndre Fischer 17819dd622cdSAndre Fischer=head2 CheckLink ($url) 17829dd622cdSAndre Fischer 17839dd622cdSAndre Fischer Check if the file referenced by $url can be downloaded. 17849dd622cdSAndre Fischer This is determined by downloading only the header. 17859dd622cdSAndre Fischer 17869dd622cdSAndre Fischer=cut 17871108b05eSAndre Fischermy $LastCheckedURL = ""; 17889dd622cdSAndre Fischermy $LastCheckedResult = undef; 17899dd622cdSAndre Fischersub CheckLink ($) 17909dd622cdSAndre Fischer{ 17919dd622cdSAndre Fischer my ($url) = @_; 17929dd622cdSAndre Fischer 17939dd622cdSAndre Fischer if ($url ne $LastCheckedURL) 17949dd622cdSAndre Fischer { 17959dd622cdSAndre Fischer my $head = LWP::Simple::head($url); 17969dd622cdSAndre Fischer $LastCheckedURL = $url; 17979dd622cdSAndre Fischer $LastCheckedResult = !!$head; 17989dd622cdSAndre Fischer } 17999dd622cdSAndre Fischer 18009dd622cdSAndre Fischer return $LastCheckedResult; 18019dd622cdSAndre Fischer} 18029dd622cdSAndre Fischer 18039dd622cdSAndre Fischer 18049dd622cdSAndre Fischer 18059dd622cdSAndre Fischer 18069dd622cdSAndre Fischersub SignFile ($$) 18079dd622cdSAndre Fischer{ 18089dd622cdSAndre Fischer my ($signature, $filename) = @_; 18099dd622cdSAndre Fischer 18109dd622cdSAndre Fischer my $command = sprintf( 18119dd622cdSAndre Fischer "gpg --armor --output %s.asc --detach-sig %s", 18129dd622cdSAndre Fischer $filename, 18139dd622cdSAndre Fischer $filename); 18149dd622cdSAndre Fischer} 18159dd622cdSAndre Fischer 18169dd622cdSAndre Fischer 18179dd622cdSAndre Fischer 18189dd622cdSAndre Fischer 1819f219747dSAndre Fischermy $context = ProcessCommandline(@ARGV); 18201108b05eSAndre Fischermy $release_descriptor = ReadReleaseDescription($context->{'filename'}, $context); 1821f219747dSAndre Fischerif ($context->{'command'} eq "build") 1822f219747dSAndre Fischer{ 18231108b05eSAndre Fischer WriteMakefile($release_descriptor, $context); 1824f219747dSAndre Fischer} 1825f219747dSAndre Fischerelsif ($context->{'command'} eq "upload") 1826f219747dSAndre Fischer{ 18271108b05eSAndre Fischer Upload($release_descriptor, $context); 1828f219747dSAndre Fischer} 1829f219747dSAndre Fischerelsif ($context->{'command'} eq "wiki") 1830f219747dSAndre Fischer{ 18311108b05eSAndre Fischer Wiki($release_descriptor, $context); 1832f219747dSAndre Fischer} 1833