blob: a6dd73c434b0c1e528734e9e1d48689cdcec907d [file] [log] [blame]
#!/usr/bin/env perl
# Copyright (C) 2018 Bocoup LLC. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
use strict;
use warnings;
package Test262::Import;
use Cwd qw/abs_path/;
use File::Path qw/rmtree/;
use File::Temp qw/tempdir/;
use FindBin;
use Getopt::Long qw/GetOptions/;
use Pod::Usage;
use Env qw(T262_EXEC_BIN);
my $Bin = $T262_EXEC_BIN || $FindBin::Bin;
my $test262Dir = abs_path("$Bin/../../../JSTests/test262");
my $revisionFile = abs_path("$Bin/../../../JSTests/test262/test262-Revision.txt");
my $summaryFile = abs_path("$Bin/../../../JSTests/test262/latest-changes-summary.txt");
my $sourceDir;
my $remoteUrl;
my $branch;
main();
sub processCLI {
my $help = 0;
GetOptions(
's|src=s' => \$sourceDir,
'r|remote=s' => \$remoteUrl,
'b|branch=s' => \$branch,
'h|help' => \$help,
);
if ($help) {
pod2usage(-exitstatus => 0, -verbose => 1);
}
if ($sourceDir and $remoteUrl) {
print "Please specify only a single location for the Test262 repository.\n\n";
pod2usage(-exitstatus => 2, -verbose => 1);
};
if ($sourceDir) {
if (not -d $sourceDir
or not -d "$sourceDir/.git"
or not -d "$sourceDir/test"
or not -d "$sourceDir/harness") {
print "$sourceDir does not exist or is not a valid Test262 folder.\n\n";
pod2usage(-exitstatus => 3, -verbose => 1);
};
if (abs_path($sourceDir) eq $test262Dir) {
print "$sourceDir cannot be the same as the current Test262 folder.\n\n";
pod2usage(-exitstatus => 4, -verbose => 1);
}
} else {
$remoteUrl ||= 'git@github.com:tc39/test262.git';
$branch ||= 'main';
}
print "Settings:\n";
print "Source: $sourceDir\n" if $sourceDir;
print "Remote: $remoteUrl\n" if $remoteUrl;
print "Branch: $branch\n" if $remoteUrl;
print "--------------------------------------------------------\n\n";
}
sub main {
my $startTime = time();
processCLI();
if ($remoteUrl) {
processRemote();
}
# Get last imported revision
my $revision = getRevision();
if (!$remoteUrl) {
# Verify if the $sourceDir folder is clean
my $dirty = qx(git -C $sourceDir status --porcelain);
chomp $dirty;
if ($dirty) {
die "Test262 at $sourceDir has unstaged/uncommited changes.";
}
}
my ($newRevision, $newTracking) = getNewRevision();
if (defined $revision and $newRevision eq $revision) {
print 'Same revision, no need to import.';
exit 0;
}
my $summary = getSummary();
print "Summary of changes:\n$summary\n\n" if $summary;
transferFiles();
reportNewRevision($newRevision, $newTracking);
saveSummary($summary);
if ($remoteUrl) {
rmtree($sourceDir);
}
my $endTime = time();
my $totalTime = $endTime - $startTime;
print "\nDone in $totalTime seconds!\n";
}
sub printAndRun {
my ($command) = @_;
print "> $command\n\n";
return qx/$command/;
}
sub processRemote {
$sourceDir = tempdir( CLEANUP => 1 );
print "Importing Test262 from git\n";
printAndRun("git clone -b $branch --depth=1 $remoteUrl $sourceDir");
}
sub transferFiles {
# Remove previous Test262 folders
printAndRun("rm -rf $test262Dir\/harness") if -e "$test262Dir/harness";
printAndRun("rm -rf $test262Dir\/test") if -e "$test262Dir/test";
# Copy from source
printAndRun("mv $sourceDir\/harness $test262Dir");
printAndRun("mv $sourceDir\/test $test262Dir");
}
sub getRevision {
open(my $revfh, '<', $revisionFile) or die $!;
my $revision;
my $contents = join("\n", <$revfh>);
# Some cheap yaml parsing, the YAML module is a possible alternative
if ($contents =~ /test262 revision\: (\w*)/) {
$revision = $1;
}
close($revfh);
return $revision;
}
sub getNewRevision {
my $tracking = qx/git -C $sourceDir ls-remote --get-url/;
chomp $tracking;
my $branch = qx/git -C $sourceDir rev-parse --abbrev-ref HEAD/;
chomp $branch;
my $revision = qx/git -C $sourceDir rev-parse HEAD/;
chomp $revision;
print "New tracking: $tracking\n";
print "From branch: $branch\n";
print "New revision: $revision\n\n";
if (!$revision or !$tracking or !$branch) {
die 'Something is wrong in the source git.';
}
return $revision, $tracking;
}
sub getSummary {
my $summary = '';
$summary = qx(git diff --no-index --name-status --diff-filter=ADRM -- $test262Dir/harness $sourceDir/harness);
$summary .= qx(git diff --no-index --name-status --diff-filter=ADRM -- $test262Dir/test $sourceDir/test);
chomp $summary;
$summary =~ s/\s+$test262Dir\// /g;
$summary =~ s/\s+$sourceDir\// /g;
return $summary;
}
sub reportNewRevision {
my ($revision, $tracking) = @_;
open(my $fh, '>', $revisionFile) or die $!;
print $fh "test262 remote url: $tracking\n";
print $fh "test262 revision: $revision\n";
close $fh;
}
sub saveSummary {
my ($summary) = @_;
open(my $fh, '>', $summaryFile) or die $!;
print $fh $summary;
close $fh;
}
__END__
=head1 DESCRIPTION
This program will import Test262 tests from a repository folder.
=head1 SYNOPSIS
Run using native Perl:
=over 8
test262-import
test262-import -s $source
test262-import -r https://github.com/tc39/test262
test262-import -r https://github.com/tc39/test262 -b es6
=back
=head1 OPTIONS
=over 8
=item B<--help, -h>
Print a brief help message.
=item B<--src, -s>
Specify the folder for Test262's repository.
=item B<--remote, -r>
Specify a remote Test262's repository. Defaults to 'git@github.com:tc39/test262.git'.
=item B<--branch, -b>
Specify a branch to be used for a remote Test262. Defaults to `main`.
=back
=cut