releasing/cbrtools/perl/MakeSnapShot
author jjkang
Wed, 30 Jun 2010 11:35:58 +0800
changeset 607 378360dbbdba
parent 602 3145852acc89
permissions -rw-r--r--
Merge missed changeset 11 (raptor v2.14 and helium 10.0)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
602
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     1
#!perl
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     2
# Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     3
# All rights reserved.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     4
# This component and the accompanying materials are made available
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     5
# under the terms of the License "Eclipse Public License v1.0"
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     6
# which accompanies this distribution, and is available
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     7
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     8
# 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
     9
# Initial Contributors:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    10
# Nokia Corporation - initial contribution.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    11
# 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    12
# Contributors:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    13
# 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    14
# Description:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    15
# 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    16
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    17
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    18
use strict;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    19
use FindBin;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    20
use lib "$FindBin::Bin";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    21
use Getopt::Long;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    22
use IniData;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    23
use EnvDb;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    24
use CommandController;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    25
use Utils;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    26
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    27
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    28
# Constants.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    29
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    30
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    31
my $KMissingFileName = Utils::PrependEpocRoot("\\__missing.txt");
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    32
my $KCompsFileName = Utils::PrependEpocRoot("\\__comps.txt");
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    33
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    34
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    35
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    36
# Globals.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    37
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    38
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    39
my $verbose = 0;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    40
my $noIgnores = 0;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    41
my $fileName;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    42
my $iniData = IniData->New();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    43
my $commandController = CommandController->New($iniData, 'MakeSnapShot');
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    44
my $force;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    45
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    46
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    47
# Main.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    48
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    49
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    50
ProcessCommandLine();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    51
MakeSnapShot();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    52
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    53
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    54
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    55
# Subs.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    56
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    57
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    58
sub ProcessCommandLine {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    59
  Getopt::Long::Configure ('bundling');
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    60
  my $help;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    61
  GetOptions('h' => \$help, 'i' => \$noIgnores, 'v+' => \$verbose, 'f' => \$force);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    62
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    63
  if ($help) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    64
    Usage(0);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    65
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    66
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    67
  $fileName = shift @ARGV;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    68
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    69
  unless ($fileName and scalar(@ARGV) == 0) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    70
    print "Error: Invalid number of arguments\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    71
    Usage(1);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    72
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    73
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    74
  unless ($fileName =~ /\.zip$/i) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    75
    $fileName .= '.zip';
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    76
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    77
  Utils::AbsoluteFileName(\$fileName);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    78
}
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    79
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    80
sub Usage {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    81
  my $exitCode = shift;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    82
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    83
  Utils::PrintDeathMessage($exitCode, "\nUsage: makesnapshot [options] <snap_shot_file_name>
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    84
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    85
options:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    86
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    87
  -h  help
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    88
  -i  include files that are normally ignored (e.g. \\epoc32\\build\\...)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    89
  -f  (deprecated)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    90
  -v  verbose output (-vv very verbose)\n");
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    91
}
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    92
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    93
sub MakeSnapShot {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    94
  if (-e $fileName) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    95
    die "Error: \"$fileName\" already exists\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    96
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    97
  my $envDb = EnvDb->Open($iniData, $verbose);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    98
  my $compsPendingRelease = $envDb->ComponentsPendingRelease();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    99
  if (scalar (keys %$compsPendingRelease) > 0) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   100
    die "Error: Can't make a snap shot of an environment contains components that are pending release\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   101
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   102
  (my $overallStatus, undef, my $dirtyComps, my $unaccountedFiles, my $duplicates) = $envDb->CheckEnv(1, $noIgnores);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   103
  if ($overallStatus == EnvDb::STATUS_CLEAN) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   104
    print "Environment clean, aborting snap shot creation\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   105
    return;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   106
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   107
  if (scalar (@$duplicates) > 0) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   108
    die "Error: Unexpected duplicates\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   109
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   110
  my @dirtyFiles;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   111
  foreach my $thisUnaccountedFile (@$unaccountedFiles) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   112
    push (@dirtyFiles, Utils::RemoveEpocRoot($thisUnaccountedFile));
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   113
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   114
  my @missingFiles;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   115
  foreach my $thisComp (@$dirtyComps) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   116
    my $binaryList = $envDb->ListBins($thisComp->{comp});
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   117
    shift @$binaryList; # Throw away list header;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   118
    foreach my $thisFile (@$binaryList) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   119
      if ($thisFile->[1] eq EnvDb::STATUS_STRING_FAILED) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   120
	push (@dirtyFiles, Utils::RemoveEpocRoot($thisFile->[0]));
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   121
      }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   122
      elsif ($thisFile->[1] eq EnvDb::STATUS_STRING_MISSING) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   123
	push (@missingFiles, Utils::RemoveEpocRoot($thisFile->[0]));
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   124
      }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   125
    }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   126
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   127
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   128
  open (MISSING, ">$KMissingFileName") or die "Error: Couldn't open \"$KMissingFileName\" for writing\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   129
  foreach my $thisFile (@missingFiles) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   130
    print MISSING "$thisFile\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   131
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   132
  close (MISSING);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   133
  push (@dirtyFiles, Utils::RemoveEpocRoot($KMissingFileName));
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   134
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   135
  my $versionInfo = $envDb->VersionInfo();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   136
  open (COMPS, ">$KCompsFileName") or die "Error: Couldn't open \"$KCompsFileName\" for writing\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   137
  foreach my $thisComp (sort keys %$versionInfo) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   138
    print COMPS "$thisComp $versionInfo->{$thisComp}\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   139
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   140
  close (COMPS);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   141
  push (@dirtyFiles, Utils::RemoveEpocRoot($KCompsFileName));
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   142
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   143
  Utils::ZipList($fileName, \@dirtyFiles, $verbose, 0, Utils::EpocRoot());
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   144
  Utils::SetFileReadOnly($fileName);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   145
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   146
  unlink ($KMissingFileName) or die "Error: Couldn't delete \"$KMissingFileName\": $!\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   147
  unlink ($KCompsFileName) or die "Error: Couldn't delete \"$KMissingFileName\": $!\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   148
  
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   149
  print "Snapshot \"$fileName\" successfully made\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   150
}
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   151
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   152
__END__
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   153
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   154
=head1 NAME
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   155
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   156
MakeSnapShot - Captures all dirty files in an environment into a user specified zip file that can be used to reproduce the environment.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   157
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   158
=head1 SYNOPSIS
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   159
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   160
  makesnapshot [options] <snap_shot_file_name>
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   161
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   162
options:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   163
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   164
  -h  help
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   165
  -i  include files that are normally ignored (e.g. \epoc32\build\...)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   166
  -v  verbose output (-vv very verbose)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   167
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   168
=head1 DESCRIPTION
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   169
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   170
The release tools exist to make it relatively straight forward to share binary files in a controlled way. In order to acheive a suitable level of control, a fair amount of rigor is imposed on users when they are making releases. There are times when this is inappropriate. For example, if a user wants to temporarily capture the current state of their environment. The commands C<MakeSnapShot> and C<InstallSnapShot> exist to make it easy to accurately capture the current state of an environment, and subsequently revert to it, without the overhead of doing a full environment release. Snap shots should only be used in preference to full environment releases when there is a B<temporary> need to capture an environment, because:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   171
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   172
=over 4
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   173
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   174
=item 1
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   175
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   176
No mechansims are provided for exporting or importing snap shots.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   177
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   178
=item 2
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   179
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   180
No release notes are provided with snap shots.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   181
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   182
=item 3
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   183
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   184
The contents of snap shots are inherently dirty - they consist of all the files that could not be accounted for with proper releases. Reliance on snap shots as a means of distributing software would therefore eventually become a self defeating activity since the snap shot files would get larger and larger over time.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   185
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   186
=back
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   187
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   188
C<MakeSnapShot> generates a zip file that contains all the dirty files currently present in the environment. It makes no attempt to understand which component own which files. It also stores some metadata in the zip file; a list of the component versions currently installed, and a list of files that are currently missing from the environment. This can subsequently be used by C<InstallSnapShot> to revert to the snap shot state.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   189
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   190
=head1 STATUS
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   191
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   192
Supported. If you find a problem, please report it to us.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   193
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   194
=head1 KNOWN BUGS
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   195
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   196
None.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   197
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   198
=head1 COPYRIGHT
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   199
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   200
 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   201
 All rights reserved.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   202
 This component and the accompanying materials are made available
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   203
 under the terms of the License "Eclipse Public License v1.0"
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   204
 which accompanies this distribution, and is available
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   205
 at the URL "http://www.eclipse.org/legal/epl-v10.html".
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   206
 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   207
 Initial Contributors:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   208
 Nokia Corporation - initial contribution.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   209
 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   210
 Contributors:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   211
 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   212
 Description:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   213
 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   214
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   215
=cut