releasing/cbrtools/perl/GetEnv
author Bob Rosenberg <bob.rosenberg@nokia.com>
Mon, 20 Sep 2010 10:55:43 +0100
changeset 658 cab9da9b71bb
parent 602 3145852acc89
permissions -rw-r--r--
Test and fail for badly invalid unit elements when joining
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 RelData;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    24
use EnvDb;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    25
use CommandController;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    26
use GetEnv;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    27
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    28
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    29
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    30
# Globals.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    31
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    32
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    33
my $verbose = 0;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    34
my $overwriteSource = 0;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    35
my $sourceInstallPath = undef;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    36
my $iniData = IniData->New();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    37
my $commandController = CommandController->New($iniData, 'GetEnv');
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    38
my $comp;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    39
my $ver;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    40
my $installSource = 0;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    41
my $removeSource =0;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    42
my $excludeComponents = undef;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    43
my $forceExclusion = 0;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    44
my $sourceOnly;
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
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    48
# Main.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    49
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    50
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    51
ProcessCommandLine();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    52
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    53
if ($sourceOnly) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    54
  GetEnvSource();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    55
}
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    56
else {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    57
  GetEnv::GetEnvFromRelData($iniData, $comp, $ver, $installSource, $sourceInstallPath, $overwriteSource, $removeSource, $verbose, $excludeComponents, $forceExclusion);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    58
  print "Checking environment...\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    59
  my $envDb = EnvDb->Open($iniData, $verbose);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    60
  (my $status) = $envDb->CheckEnv();
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    61
  print "Status: ", EnvDb::StatusString($status), "\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    62
}
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    63
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    64
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    65
# Subs.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    66
#
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    67
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    68
sub ProcessCommandLine {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    69
  Getopt::Long::Configure ("bundling");
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    70
  my $help;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    71
  GetOptions('h' => \$help, 's' => \$installSource, 'o' => \$overwriteSource, 'r' => \$removeSource, 'v+' => \$verbose,  'i=s' => \$sourceInstallPath, 'x=s' => \$excludeComponents, 'f' => \$forceExclusion, 'source-only' => \$sourceOnly);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    72
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    73
  if ($help) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    74
    Usage(0);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    75
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    76
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    77
  $comp = shift @ARGV;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    78
  $ver = shift @ARGV;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    79
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    80
  unless (defined $comp and defined $ver and $#ARGV = -1) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    81
    print "Error: Invalid arguments\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    82
    Usage(1);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    83
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    84
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    85
  if ($sourceInstallPath and not ($installSource || $sourceOnly )) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    86
    print "Error: Invalid options - cannot specify install path (using -i) without installing source (using -s or --source-only)\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    87
    Usage(1);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    88
  }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    89
  
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    90
  Utils::CheckDirectoryName($sourceInstallPath) if defined $sourceInstallPath;
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 Usage {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    94
  my $exitCode = shift;
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    95
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    96
  Utils::PrintDeathMessage($exitCode, "\nUsage: getenv [options] <component> <external_version>
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    97
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    98
options:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
    99
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   100
-h  help
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   101
-s  install source also
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   102
-r  remove source which belongs to components deleted during upgrade
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   103
-i  <source_install_directory>
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   104
-o  overwrite any existing source and binaries (including pending release components)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   105
-v  verbose output (-vv very verbose)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   106
-x  <component_name> to exclude from installation or <file> with list of components to exclude (sets -r)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   107
-f  overrides the user prompt when removing components specified with the -x flag. Does nothing if -x not defined
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   108
--source-only Installs the source code for any environment, irrespective of whether it is the current environment or not\n");
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   109
}
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   110
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   111
sub GetEnvSource {   
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   112
    my $reldata = RelData->Open($iniData, $comp, $ver, $verbose);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   113
    my $components = $reldata->Environment();    
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   114
    my $envDb = EnvDb->Open($iniData, $verbose);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   115
    
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   116
    if (defined $excludeComponents) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   117
      $components = GetEnv::FilterCompsToExclude($components, $excludeComponents, $verbose, $forceExclusion);
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   118
    }
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   119
    
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   120
    foreach my $thisComp (sort keys %{$components}) {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   121
        eval {
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   122
            print "Getting source for $thisComp $components->{$thisComp}...\n";
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   123
            $envDb->UnpackSource($thisComp, $components->{$thisComp}, $sourceInstallPath || "\\", $overwriteSource, $verbose);     
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
__END__
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   129
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   130
=head1 NAME
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   131
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   132
GetEnv - Installs the environment from which a component release was made.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   133
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   134
=head1 SYNOPSIS
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   135
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   136
  getenv [options] <component> <version>
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   137
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   138
options:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   139
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   140
  -h  help
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   141
  -s  install source also
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   142
  -r  removes source which belongs to components deleted during upgrade
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   143
  -i  <source_install_directory>
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   144
  -o  overwrite any existing source and binaries (including components pending release)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   145
  -v  verbose output (-vv very verbose)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   146
  -x  <component_name> to exclude from installation or <file> with list of components to exclude (sets -r)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   147
  -f  overrides the user prompt when removing components specified with the -x flag. Does nothing if -x not defined.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   148
  --source-only Installs the source code for any environment, irrespective of whether it is the current environment or not
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   149
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   150
=head1 DESCRIPTION
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   151
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   152
When a release is made, a description of the environment it was made from is stored with it. C<GetEnv> reads this and installs the necessary components into the current environment in order to make it identical to the environment from which the release was made. Note, the term I<environment> is used to mean the F<\epoc32> tree. C<GetEnv> will optionally install source code into the root of the current drive, but it makes no attempt to verify the cleanliness of these directories.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   153
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   154
Components that were present in the release environment, but which are not present in the current environment are simply installed. Components of a different version in the current environment to that of the release environment are upgraded. The upgrade process involves removing the currently installed binaries, and then unpacking the new binaries. The binaries of components that have the same version in the current environment to that of the release environment are checked against the time stamp information that was stored when they were installed. If the check fails, the component is upgraded. If it succeeds, the component left untouched.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   155
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   156
As well as overwriting existing source code, C<-o> will overwrite any binaries which are left on the drive. There will only be leftover binaries in exceptional circumstances; normally C<getenv> will remove old versions of components before trying to install new ones. C<-o> will also force 'pending release' components to be removed if necessary.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   157
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   158
Unrequired components, (e.g. documentation), can be optionally excluded from being installed using the -x flag and specifying the component name or a file which contains a list of component names (Wildcards are supported). If the unrequired component exists in the current environment the binaries and source will be removed from the current environment, if it does not currently exist the component will simply not be installed if it is in the new environment. This option should be used cautiously especially if making releases from your local work area.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   159
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   160
Examples of -x flag:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   161
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   162
	getenv -vos gt_techview_baseline <some_version> -x tools_e32toolp
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   163
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   164
	This will exclude the component tools_e32toolp from the new installation if it exists in the archive
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   165
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   166
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   167
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   168
	getenv -vos gt_techview_baseline <some_version> -x tools*
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   169
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   170
	This will exclude any components which begin with the string "tools" in their name from the new installation
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   171
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   172
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   173
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   174
	getenv -vos gt_techview_baseline <some_version> -x d:\exclude.txt
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   175
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   176
	This will exclude any components that are mentioned in the file from the new installation if they exist in the archive
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   177
	(File can be named anything)
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   178
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   179
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   180
	Format of the file:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   181
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   182
	component_one
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   183
	component_two
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   184
	component_three
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   185
	component*
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   186
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   187
	(All components are to be on seperate lines, empty lines are permitted).
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   188
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   189
	When using the * wildcard this must be at the end of the line.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   190
	
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   191
=head1 KNOWN BUGS
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   192
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   193
None.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   194
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   195
=head1 COPYRIGHT
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   196
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   197
 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   198
 All rights reserved.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   199
 This component and the accompanying materials are made available
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   200
 under the terms of the License "Eclipse Public License v1.0"
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   201
 which accompanies this distribution, and is available
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   202
 at the URL "http://www.eclipse.org/legal/epl-v10.html".
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   203
 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   204
 Initial Contributors:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   205
 Nokia Corporation - initial contribution.
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   206
 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   207
 Contributors:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   208
 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   209
 Description:
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   210
 
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   211
3145852acc89 add releasing to new structure
jjkang
parents:
diff changeset
   212
=cut