releasing/cbrtools/perl/MakeRel.pm
changeset 602 3145852acc89
equal deleted inserted replaced
600:6d08f4a05d93 602:3145852acc89
       
     1 # Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 # All rights reserved.
       
     3 # This component and the accompanying materials are made available
       
     4 # under the terms of the License "Eclipse Public License v1.0"
       
     5 # which accompanies this distribution, and is available
       
     6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 # 
       
     8 # Initial Contributors:
       
     9 # Nokia Corporation - initial contribution.
       
    10 # 
       
    11 # Contributors:
       
    12 # 
       
    13 # Description:
       
    14 # 
       
    15 #
       
    16 
       
    17 package MakeRel;
       
    18 
       
    19 use strict;
       
    20 use File::Path;
       
    21 use File::Spec;
       
    22 use File::Basename;
       
    23 use IniData;
       
    24 use EnvDb;
       
    25 use MrpData;
       
    26 use RelData;
       
    27 use CatData;
       
    28 use Utils;
       
    29 use Symbian::CBR::Component::Manifest;
       
    30 use Cwd;
       
    31 
       
    32 #
       
    33 # Public.
       
    34 #
       
    35 
       
    36 sub MakeReleases {
       
    37   my $self;
       
    38   $self->{iniData} = shift;
       
    39   $self->{envDb} = shift;
       
    40   $self->{mrpData} = shift;
       
    41   $self->{notesSrc} = shift;
       
    42   $self->{toolName} = shift;
       
    43   $self->{verbose} = shift;
       
    44   $self->{project} = shift;
       
    45   $self->{useCachedManifest} = shift;
       
    46 
       
    47   bless $self, "MakeRel";
       
    48 
       
    49   if (scalar(@{$self->{mrpData}}) == 0) { # Abort if there's nothing to do.
       
    50     return;
       
    51   }
       
    52   if (!$self->CheckArchive()) { # Abort if any of the releases already exist
       
    53     return;
       
    54   }
       
    55 
       
    56   my $versionInfo = $self->VersionInfo();
       
    57   eval {
       
    58     $self->GenerateReleaseFiles($versionInfo);
       
    59   };
       
    60   if ($@) {
       
    61     print $@;
       
    62 
       
    63     if($self->{toolName} =~ /MakeEnv/i){
       
    64       print "\nError: Unable to create environment successfully, archive might be corrupted.\n";
       
    65     }
       
    66     else{
       
    67       print "\nError: Unable to create component release successfully, archive might be corrupted.\n";
       
    68     }
       
    69 
       
    70     $self->Cleanup();
       
    71     return;
       
    72   }
       
    73 
       
    74   # Now that we know all releases have been successfully made, update the environment database.
       
    75   foreach my $thisMrpData (@{$self->{mrpData}}) {
       
    76     my $comp = $thisMrpData->Component();
       
    77     my $ver = $thisMrpData->ExternalVersion();
       
    78     $self->{envDb}->SetVersion($comp, $ver);
       
    79     $self->{envDb}->GenerateSignature($comp, $ver);
       
    80     $self->{envDb}->SetMrpName($comp, $thisMrpData->MrpName());
       
    81     $self->{envDb}->SetStatus($comp, EnvDb::STATUS_CLEAN);
       
    82   }
       
    83 }
       
    84 
       
    85 
       
    86 #
       
    87 # Private.
       
    88 #
       
    89 
       
    90 sub VersionInfo {
       
    91   my $self = shift;
       
    92 
       
    93   # Get a copy of the current version information from the environment database and update it with the new versions.
       
    94   my $versionInfo = $self->{envDb}->VersionInfo();
       
    95   foreach my $thisMrpData (@{$self->{mrpData}}) {
       
    96     $versionInfo->{lc($thisMrpData->Component())} = $thisMrpData->ExternalVersion();
       
    97   }
       
    98 
       
    99   return $versionInfo;
       
   100 }
       
   101 
       
   102 sub CheckArchive {
       
   103   my $self = shift;
       
   104   my $good = 1;
       
   105   foreach my $thisMrpData (@{$self->{mrpData}}) {
       
   106     if (!$self->CheckDirs($thisMrpData)) {
       
   107       $good = 0; # Continue and check the rest
       
   108     }
       
   109   }
       
   110   return $good;
       
   111 }
       
   112 
       
   113 sub GenerateReleaseFiles {
       
   114   my $self = shift;
       
   115   my $versionInfo = shift;
       
   116   my $numMrps = scalar(@{$self->{mrpData}});
       
   117   foreach my $thisMrpData (@{$self->{mrpData}}) {
       
   118     $self->MakeDirs($thisMrpData);
       
   119     $self->ZipSource($thisMrpData);
       
   120     $self->ZipBinaries($thisMrpData);
       
   121     $self->ZipExports($thisMrpData);
       
   122     $self->WriteRelData($thisMrpData, $versionInfo);
       
   123     $self->WriteManifest($thisMrpData);
       
   124 
       
   125     # This line must come after the others, because with a project-based archive path configuration it relies on
       
   126     # LocalArchivePathForNewOrExistingComponent finding the directories created above.
       
   127     my $comp = $thisMrpData->Component();
       
   128     my $extVer = $thisMrpData->ExternalVersion();
       
   129     my $intVer = $thisMrpData->InternalVersion();
       
   130     unless (defined $intVer) {
       
   131       $intVer = '';
       
   132     }
       
   133     my $relDir = $self->LocalArchivePath($thisMrpData);
       
   134     Utils::SetFileReadOnly($relDir);
       
   135     print "Made $comp $extVer $intVer\n";
       
   136   }
       
   137 }
       
   138 
       
   139 sub ComponentDir {
       
   140   require Carp;
       
   141   confess("Obsolete method called");
       
   142 }
       
   143 
       
   144 sub ReleaseDir {
       
   145   require Carp;
       
   146   confess("Obsolete method called");
       
   147 }
       
   148 
       
   149 sub CheckDirs {
       
   150   my $self = shift;
       
   151   my $mrpData = shift;
       
   152   my $relDir = $self->LocalArchivePath($mrpData);
       
   153   if (-e $relDir) {
       
   154     print STDERR "Error: $relDir already exists\n";
       
   155     return 0;
       
   156   }
       
   157   return 1;
       
   158 }
       
   159 
       
   160 sub MakeDirs {
       
   161   my $self = shift;
       
   162   my $mrpData = shift;
       
   163   my $relDir = $self->LocalArchivePath($mrpData);
       
   164   unless (-e $relDir) {
       
   165     Utils::MakeDir($relDir);
       
   166   }
       
   167 }
       
   168 
       
   169 sub ZipSource {
       
   170   my $self = shift;
       
   171   my $mrpData = shift;
       
   172   my @categories = @{$mrpData->SourceCategories()};
       
   173   my $zipName;
       
   174 
       
   175   foreach my $category (@categories) {
       
   176     my @sourceFiles = @{$mrpData->Source($category)};
       
   177     if (@sourceFiles) {
       
   178       $zipName = $self->LocalArchivePath($mrpData) . "\\source".uc($category).".zip";
       
   179 
       
   180       Utils::ZipSourceList($zipName, \@sourceFiles, $self->{verbose}, Utils::SourceRoot(), $self->{iniData});
       
   181 
       
   182       Utils::SetFileReadOnly($zipName);
       
   183     }
       
   184   }
       
   185   if ($self->{verbose} > 1 and not defined $zipName) {
       
   186     print "No source for " . $mrpData->Component() . "\n";
       
   187   }
       
   188 }
       
   189 
       
   190 sub ZipBinaries {
       
   191   my $self = shift;
       
   192   my $mrpData = shift;
       
   193   foreach my $thisBinCat (@{$mrpData->BinaryCategories()}) {
       
   194     my $bins = $mrpData->Binaries($thisBinCat);
       
   195     if ($bins and scalar(@$bins) > 0) {
       
   196       my $zipName;
       
   197       if ($thisBinCat eq 'unclassified') {
       
   198         $zipName = $self->LocalArchivePath($mrpData) . "\\binaries.zip";
       
   199       }
       
   200       else {
       
   201         $zipName = $self->LocalArchivePath($mrpData) . "\\binaries_$thisBinCat.zip";
       
   202       }
       
   203       Utils::ZipList($zipName, $bins, $self->{verbose}, 0, Utils::EpocRoot());
       
   204       Utils::SetFileReadOnly($zipName);
       
   205     }
       
   206   }
       
   207 }
       
   208 
       
   209 sub ZipExports {
       
   210   my $self = shift;
       
   211   my $mrpData = shift;
       
   212 
       
   213   foreach my $thisExportCat (@{$mrpData->ExportCategories()}) {
       
   214     my $exports = $mrpData->Exports($thisExportCat);
       
   215     if ($exports and scalar(@$exports) > 0) {
       
   216       my $zipName = $self->LocalArchivePath($mrpData) . "\\exports".uc($thisExportCat).".zip";
       
   217       Utils::ZipList($zipName, $exports, $self->{verbose}, 0, Utils::EpocRoot());
       
   218       Utils::SetFileReadOnly($zipName);
       
   219       # Need to create an exports<CAT>.txt file which details necessary info...
       
   220       my $txtName = $self->LocalArchivePath($mrpData) . "\\exports".uc($thisExportCat).".txt";
       
   221       CatData->New($self->{iniData}, $txtName, $mrpData, uc($thisExportCat));
       
   222     }
       
   223   }
       
   224 }
       
   225 
       
   226 sub WriteRelData {
       
   227   my $self = shift;
       
   228   my $mrpData = shift;
       
   229   my $versionInfo = shift;
       
   230 
       
   231   my $notesSource = $self->{notesSrc};
       
   232   if (defined $notesSource) {
       
   233     Utils::CheckExists($notesSource);
       
   234     Utils::CheckIsFile($notesSource);
       
   235   }
       
   236   else {
       
   237     $notesSource = Utils::PrependSourceRoot($mrpData->NotesSource());
       
   238   }
       
   239   my $relData = RelData->New($self->{iniData}, $mrpData, $notesSource, $versionInfo, $self->{toolName}, $self->{verbose}, undef, $self->{project}); # undef = dontPersist
       
   240 }
       
   241 
       
   242 sub WriteManifest {
       
   243   my $self = shift;
       
   244   my $mrpData = shift;
       
   245   my $componentName = $mrpData->Component();
       
   246   my $manifest = undef;
       
   247   
       
   248   
       
   249   if ($self->{useCachedManifest}) {
       
   250     #Check if manifest file is available in temp location
       
   251     my $manifestTempFile = File::Spec->catfile( File::Spec->tmpdir(), "manifest_".$componentName.".xml" );
       
   252     
       
   253     if (-e $manifestTempFile ) {
       
   254       #Construct manifest object from the manifest file
       
   255       $manifest = Symbian::CBR::Component::Manifest->new( $manifestTempFile );
       
   256       
       
   257       #Delete the temp manifest file
       
   258       my $unlinkCount = 100;
       
   259       while(-e $manifestTempFile and $unlinkCount > 0){
       
   260         unlink($manifestTempFile) or print "Warning: unlink $manifestTempFile failed[$unlinkCount].\n";
       
   261         $unlinkCount--;
       
   262       }
       
   263       if ( $unlinkCount == 0 ) {
       
   264         die "Error: unlink $manifestTempFile failed.\n";
       
   265       }
       
   266     }
       
   267   }
       
   268   
       
   269   if (!defined $manifest) {
       
   270     my $mrpName = Utils::RelativeToAbsolutePath( $mrpData->MrpName(), $mrpData->{iniData}, SOURCE_RELATIVE );
       
   271     
       
   272     #Construct manifest object from MRP file
       
   273     $manifest = Symbian::CBR::Component::Manifest->new( $mrpName );
       
   274   }
       
   275   
       
   276   #Save the manifest file to the archive release location for the component
       
   277   $manifest->Save ( $self->LocalArchivePath($mrpData) );
       
   278 }
       
   279 
       
   280 sub Cleanup {
       
   281   my $self = shift;
       
   282   if ($self->{verbose}) { print "Cleaning up...\n"; }
       
   283   foreach my $thisMrpData (@{$self->{mrpData}}) {
       
   284     my $relDir = $self->LocalArchivePath($thisMrpData);
       
   285     if (-e $relDir) {
       
   286       if ($self->{verbose}) { print "Deleting $relDir...\n"; }
       
   287       my $origDir = cwd();
       
   288       
       
   289       chdir(dirname($relDir)); #If you try to rmtree a UNC path the cwd must also be a UNC path
       
   290       rmtree ($relDir);
       
   291       chdir($origDir);
       
   292     }
       
   293   }
       
   294 }
       
   295 
       
   296 sub LocalArchivePath {
       
   297   my $self = shift;
       
   298   my $mrpData = shift;
       
   299   my $name = $mrpData->Component();
       
   300   my $ver = $mrpData->ExternalVersion();
       
   301 
       
   302   if (not exists $self->{pathCache}->{$name}->{$ver}) {
       
   303     $self->{pathCache}->{$name}->{$ver} = $self->{iniData}->PathData->LocalArchivePathForExistingOrNewComponent($name, $ver, $self->{project});
       
   304   }
       
   305 
       
   306   return $self->{pathCache}->{$name}->{$ver};
       
   307 }
       
   308 
       
   309 1;
       
   310 
       
   311 =head1 NAME
       
   312 
       
   313 MakeRel.pm - Provides an interface for making releases.
       
   314 
       
   315 =head1 INTERFACE
       
   316 
       
   317 =head2 MakeReleases
       
   318 
       
   319 Expects to be passed an C<IniData> reference, an C<EnvDb> reference, a reference to a list of C<MrpData> objects, the name of a notes source file, the name of the tool using C<MakeRel> and a verbosity level. Firstly, the binary files referred to by the C<MrpData> objects are cross checked to ensure that more than one component isn't attempting to release the same file. Dies if this is the case. Secondly, generates release directories and files for each C<MrpData> object. Thirdly, updates local signature files and the environment database.
       
   320 
       
   321 =head1 KNOWN BUGS
       
   322 
       
   323 None.
       
   324 
       
   325 =head1 COPYRIGHT
       
   326 
       
   327  Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
       
   328  All rights reserved.
       
   329  This component and the accompanying materials are made available
       
   330  under the terms of the License "Eclipse Public License v1.0"
       
   331  which accompanies this distribution, and is available
       
   332  at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
   333  
       
   334  Initial Contributors:
       
   335  Nokia Corporation - initial contribution.
       
   336  
       
   337  Contributors:
       
   338  
       
   339  Description:
       
   340  
       
   341 
       
   342 =cut