Synchronize streams across repositories
You can use the source control command line tool to synchronize streams or repository workspaces across repositories.
Synchronize streams
You can back up repository files by synchronizing streams or repository workspaces across repositories. You can also deliver changes to a source stream in the source repository and back up changes onto a target stream, either in the same repository or a different repository. The source and the target streams are synchronized when they have the same set of data.
JSON output
You can use the command line tool to produce JavaScript Object Notation (JSON). JSON output provides a scripting capability for builds and other scripting scenarios. The command line tool commands that support JSON have a switch to turn on the JSON output: --json or -j. You can also enable scripting by setting the json.output preference to true in the preferences.properties file.
Examples
You can use JSON output and scripting to synchronize two streams. You can use any scripting language that can parse the JSON output. The following example uses a Perl script. You must install the JSON Perl module, JSON.pm, to parse the JSON output of a command and convert it to a Perl data structure.
To validate whether a JSON Perl module is installed, from the command line, run the following command: perl -MJSON -e 1
If the command does not result in errors, the module is installed. If the module is not installed, complete the installation instructions http://search.cpan.org/~makamaka/JSON-2.53/lib/JSON.pm.
The following example JSON Perl script describes how to synchronize source and target streams across repositories.
# /*******************************************************************************
# * Licensed Materials - Property of IBM
# * (c) Copyright IBM Corporation 2005, 2012. All Rights Reserved.
# *
# *******************************************************************************/
# Script synchronizes streams or workspaces in the same repository or accross repositories.
# Script usage: sync.pl type1 (name/alias/uuid)[@repo1] type2 (name/alias/uuid)[@repo2]
# Script usage example: sync.pl stream st1@repo1 stream st2@repo2
# Requirements:
# Install JSON module from http://search.cpan.org/~makamaka/JSON-2.53/lib/JSON.pm
use JSON;
my $srctype = $ARGV[0];
my $source = $ARGV[1];
my $tgttype = $ARGV[2];
my $target = $ARGV[3];
# Execute compare subcommand
my $result = `lscm compare $srctype $source $tgttype $target -p c --json`;
quitOnError($?, $result);
# Uncomment to print out the json result
# print $result . "\n";
# decode the result
my $json = decode_json($result);
# Get the incoming/outgoing changes
my @arr = @{$json->{direction}};
# Synchronize source and target
my $sync_result = syncUp(\@arr, $source, $target);
print "\nSource & Target are in sync\n";
#
# Routine that prints the error message and quits
#
sub quitOnError {
my $error_code = shift;
my $error = shift;
if ($error_code != 0) {
print $error . "\n";
exit($error_code);
}
}
#
# Routine to synchronize the source and target
#
sub syncUp {
my $arr_ref = shift;
my $source = shift;
my $target = shift;
my @incoming = (), @outgoing = ();
my @toAdd = () , @toReplace = () , @toRemove = ();
my $synced = 0;
# Get source repository info
my $src_uri = substr $source, (rindex($source, '@') + 1);
# Get target repository info
my $tgt_uri = substr $target, (rindex($target, '@') + 1);
# Retrieve the incoming and outgoing components
for my $entry (@$arr_ref)
{
my $dir = $entry->{"outgoing-changes"};
if ($dir eq JSON::true) {
@outgoing = @{$entry->{components}};
}
$dir = $entry->{"incoming-changes"};
if ($dir eq JSON::true) {
@incoming = @{$entry->{components}};
}
}
# Process all outgoing components. Check if there are any new component(s) in the source
# or if there are any changes (baselines, changesets) to the existing component.
for my $out_entry (@outgoing) {
if ($out_entry->{"item-type"} eq "component") {
my $found = 0;
for my $in_entry (@incoming) {
if ($in_entry->{"item-type"} eq "component") {
if ($out_entry->{name} eq $in_entry->{name}) {
$found = 1;
push(@toReplace, $out_entry->{uuid});
last;
}
}
}
if ($found == 0) {
push(@toAdd, $out_entry->{uuid});
}
}
}
# Process all incoming components. Check if there are any new components in the target
for my $in_entry (@incoming) {
if ($in_entry->{"item-type"} eq "component") {
my $found = 0;
for my $out_entry (@outgoing) {
if ($out_entry->{"item-type"} eq "component") {
if ($in_entry->{name} eq $out_entry->{name}) {
$found = 1;
last;
}
}
}
if ($found == 0) {
push(@toRemove, $in_entry->{uuid});
}
}
}
# Add components to the target
my $arrSize = @toAdd;
if ($arrSize gt 0) {
my $Comps = join(' ', @toAdd);
# run add-component command (adds the component with the intial baseline)
my $result = `lscm add component -r $src_uri $target $Comps`;
quitOnError($?, $result);
# deliver, this will make the target in sync with the current baseline of the source
$result = `lscm deliver -s $source -t $target -r $src_uri -C $Comps`;
quitOnError($?, $result);
}
# Replace components in the target
$arrSize = @toReplace;
if ($arrSize gt 0) {
my $Comps = join(' ', @toReplace);
# run replace-component command
my $result = `lscm workspace replace-component -r $src_uri $target workspace $source $Comps`;
quitOnError($?, $result);
}
# Remove components from the target
$arrSize = @toRemove;
if ($arrSize gt 0) {
my $Comps = join(' ', @toRemove);
# run remove-component command
my $result = `lscm workspace remove-component -r $tgt_uri $target $Comps`;
quitOnError($?, $result);
}
return 0;
}