...
 
Commits (12)
......@@ -32,14 +32,14 @@
# Adding an option? Grep for 'defaultGlobalOptions' in ksb::BuildContext --mpyne
use FindBin qw($RealBin);
use lib "$RealBin/../share/kdesrc-build/modules";
use lib "$RealBin/modules";
# Force all symbols to be in this package. We can tell if we're being called
# through require/eval/etc. by using the "caller" function.
package main;
use FindBin qw($RealBin);
use lib "$RealBin/../share/kdesrc-build/modules";
use lib "$RealBin/modules";
use strict;
use warnings;
......@@ -257,19 +257,16 @@ if (defined caller && caller eq 'test')
}
my $app;
our @atexit_subs;
END {
# Basically used to call the finish() handler but only when appropriate.
foreach my $sub (@atexit_subs) {
&$sub();
}
}
# Use some exception handling to avoid ucky error messages
eval
{
$app = ksb::Application->new(@ARGV);
$app->execProgramIfSet();
$app->downloadRepositoryData();
if ($app->context()->hasOption('metadata-only')) {
exit 0;
}
# Hack for debugging current state.
if (exists $ENV{KDESRC_BUILD_DUMP_CONTEXT}) {
......@@ -281,31 +278,38 @@ eval
print Data::Dumper->Dump([$app->context()], [qw(ctx)]);
}
push @atexit_subs, sub { $app->finish(99) };
my $result = $app->runAllModulePhases();
my @moduleList = $app->generateModuleList();
if (!@moduleList) {
say "No modules to build, exiting";
exit 0;
}
@atexit_subs = (); # Clear exit handlers
$app->finish($result);
my $result = $app->start(@moduleList);
$app->finish($result); # noreturn
};
if (my $err = $@)
{
if (had_an_exception()) {
print "kdesrc-build encountered an exceptional error condition:\n";
print " ========\n";
print " $err\n";
print " ========\n";
print "\tCan't continue, so stopping now.\n";
say (<<"EOM");
kdesrc-build encountered an exceptional error condition:
========
$err
========
Can't continue, so stopping now.
EOM
if ($err->{'exception_type'} eq 'Internal') {
print "\nPlease submit a bug against kdesrc-build on https://bugs.kde.org/\n"
say ("\nPlease submit a bug against kdesrc-build on https://bugs.kde.org/");
}
}
else {
# We encountered an error.
print "Encountered an error in the execution of the script.\n";
print "The error reported was $err\n";
print "Please submit a bug against kdesrc-build on https://bugs.kde.org/\n";
say (<<"EOM");
Encountered an error in the execution of the script.
The error reported was $err
Please submit a bug against kdesrc-build on https://bugs.kde.org/
EOM
}
exit 99;
......
This diff is collapsed.
......@@ -83,7 +83,6 @@ our %defaultGlobalFlags = (
"install-environment-driver" => 1, # Setup ~/.config/kde-env-*.sh for login scripts
"install-session-driver" => 0, # Above, + ~/.xsession
"purge-old-logs" => 1,
"run-tests" => 0, # 1 = make test, upload = make Experimental
"stop-on-failure" => 0,
"use-clean-install" => 0,
"use-idle-io-priority" => 0,
......@@ -115,6 +114,7 @@ our %defaultGlobalOptions = (
"persistent-data-file" => "",
"qtdir" => "",
"remove-after-install" => "none", # { none, builddir, all }
"run-tests" => 0, # 1 = make test, upload = make Experimental
"source-dir" => "$ENV{HOME}/kdesrc",
"svn-server" => "svn://anonsvn.kde.org/home/kde",
"tag" => "",
......@@ -129,6 +129,8 @@ sub new
my $self = ksb::Module::new($class, undef, 'global');
my %newOpts = (
modules => [],
# Selectors that gave rise to the resulting module list, iff given on cmdline
selectors => [],
context => $self, # Fix link to buildContext (i.e. $self)
build_options => {
global => {
......@@ -138,6 +140,15 @@ sub new
},
# Module options are stored under here as well, keyed by module->name()
},
# options loaded from cmdline, should mask options read from modules if a module
# is dynamically created (e.g. as a dependency)
cmdline_options => {
global => {
},
},
# options set in 'options' blocks, usually for dynamically-generated modules
deferred_options => {
},
# This one replaces ksb::Module::{phases}
phases => ksb::PhaseList->new(@DefaultPhases),
errors => {
......@@ -155,6 +166,7 @@ sub new
env => { },
persistent_options => { }, # These are kept across multiple script runs
ignore_list => [ ], # List of KDE project paths to ignore completely
ignored_selectors => [ ], # user-requested selectors to ignore
kde_projects_metadata => undef, # Enumeration of kde-projects
kde_dependencies_metadata => undef, # Dependency resolution of kde-projects
logical_module_resolver => undef, # For branch-group option
......@@ -526,6 +538,7 @@ sub rcFile
sub setRcFile
{
my ($self, $file) = @_;
return unless $file;
$self->{rcFiles} = [$file];
$self->{rcFile} = undef;
}
......@@ -1028,4 +1041,36 @@ sub statusViewer
return $self->{status_view};
}
# Returns a reference to a hash mapping module-names to another hash holding option key/value pairs.
sub cmdlineOptions
{
my $self = shift;
return $self->{cmdline_options};
}
# Returns a reference to a hash mapping module-names to another hash holding option key/value pairs.
sub deferredOptions
{
my $self = shift;
return $self->{deferred_options};
}
# Returns a reference to a list containing user-desired module or module-set
# selectors in order encountered on cmdline. Can be an empty listref if no
# command-line selectors were given, but won't be undef.
sub userSelectors
{
my $self = shift;
return $self->{selectors};
}
# Returns a reference to a list containing user-desired module or module-set
# selectors to ignore, in the order encountered on cmdline. Can be an empty
# listref if no command-line selectors were given, but won't be undef.
sub userIgnoredSelectors
{
my $self = shift;
return $self->{ignored_selectors};
}
1;
......@@ -21,12 +21,9 @@ sub new
my $self = {
context => $ctx,
ignoredSelectors => [ ],
# Read in from rc-file
inputModulesAndOptions => [ ],
cmdlineOptions => { },
deferredOptions => { },
# Holds Modules defined in course of expanding module-sets
definedModules => { },
......@@ -38,27 +35,6 @@ sub new
return bless $self, $class;
}
sub setCmdlineOptions
{
my ($self, $cmdlineOptionsRef) = @_;
$self->{cmdlineOptions} = $cmdlineOptionsRef;
return;
}
sub setDeferredOptions
{
my ($self, $deferredOptionsRef) = @_;
$self->{deferredOptions} = $deferredOptionsRef;
return;
}
sub setIgnoredSelectors
{
my ($self, $ignoredSelectorsRef) = @_;
$self->{ignoredSelectors} = $ignoredSelectorsRef // [ ];
return;
}
sub setInputModulesAndOptions
{
my ($self, $modOptsRef) = @_;
......@@ -75,8 +51,9 @@ sub setInputModulesAndOptions
sub _applyOptions
{
my ($self, @modules) = @_;
my $cmdlineOptionsRef = $self->{cmdlineOptions};
my $deferredOptionsRef = $self->{deferredOptions};
my $ctx = $self->{context};
my $cmdlineOptionsRef = $ctx->cmdlineOptions();
my $deferredOptionsRef = $ctx->deferredOptions();
foreach my $m (@modules) {
my $name = $m->name();
......@@ -184,9 +161,10 @@ sub _resolveSingleSelector
substr($selectorName, 0, 1, '') if $forcedToKDEProject;
# Checks cmdline options only
my $cmdlineOptionsRef = $ctx->cmdlineOptions();
my $includingDeps =
exists $self->{cmdlineOptions}->{$selectorName}->{'include-dependencies'} ||
exists $self->{cmdlineOptions}->{'global'}->{'include-dependencies'};
exists $cmdlineOptionsRef->{$selectorName}->{'include-dependencies'} ||
exists $cmdlineOptionsRef->{'global'}->{'include-dependencies'};
# See resolveSelectorsIntoModules for what the 3 "cases" mentioned below are.
......@@ -351,7 +329,7 @@ sub resolveSelectorsIntoModules
# We have to be careful to maintain order of selectors throughout.
my @outputList;
for my $selector (@selectors) {
next if list_has ($self->{ignoredSelectors}, $selector);
next if list_has ($ctx->userIgnoredSelectors(), $selector);
push @outputList, $self->_resolveSingleSelector($selector);
}
......@@ -441,8 +419,8 @@ selectors into actual modules.
=item new
Creates a new C<ModuleResolver>. You must pass the appropriate
C<BuildContext> Don't forget to call setPendingOptions(),
setIgnoredSelectors() and setInputModulesAndOptions().
C<BuildContext> Don't forget to call setPendingOptions() and
setInputModulesAndOptions().
my $resolver = ModuleResolver->new($ctx);
......@@ -460,14 +438,6 @@ are themselves hashrefs of option-name => value pairs:
mod2 => { }
})
=item setIgnoredSelectors
Declares all selectors that should be ignored by default in the process of
expanding module sets. Any modules matching these selectors would be elided
from any expanded module sets by default.
You should pass a listref of selectors.
=item setInputModulesAndOptions
Declares the list of all modules and module-sets known to the program,
......@@ -606,9 +576,8 @@ From the perspective of calling code, the 'outputs' of this module are
lists of C<Module> objects, in the order they were selected (or mentioned
in the rc-file). See expandModuleSets() and resolveSelectorsIntoModules().
Each object so returned should already have the appropriate options
included (based on the cmdlineOptions member, which should be constructed
as the union of rc-file and cmdline options).
Each object so returned should already have the appropriate options included
(based on the cmdlineOptions and deferredOptions held in the C<BuildContext>).
Note that dependency resolution is B<not> handled by this module, see
C<DependencyResolver> for that.
......
use 5.014;
use Test::More import => ['!note'];
use_ok(qw(ksb::Application));
use_ok(qw(ksb::BuildContext));
use_ok(qw(ksb::BuildException));
use_ok(qw(ksb::BuildSystem::Autotools));
use_ok(qw(ksb::BuildSystem::CMakeBootstrap));
use_ok(qw(ksb::BuildSystem::KDE4));
use_ok(qw(ksb::BuildSystem::QMake));
use_ok(qw(ksb::BuildSystem::Qt4));
use_ok(qw(ksb::BuildSystem));
use_ok(qw(ksb::Debug));
use_ok(qw(ksb::DependencyResolver));
use_ok(qw(ksb::IPC::Null));
use_ok(qw(ksb::IPC::Pipe));
use_ok(qw(ksb::IPC));
use_ok(qw(ksb::KDEProjectsReader));
use_ok(qw(ksb::Module::BranchGroupResolver));
use_ok(qw(ksb::Module));
use_ok(qw(ksb::ModuleResolver));
use_ok(qw(ksb::ModuleSet::KDEProjects));
use_ok(qw(ksb::ModuleSet::Null));
use_ok(qw(ksb::ModuleSet));
#use_ok(qw(ksb::ModuleStatusAnnouncer));
use_ok(qw(ksb::OptionsBase));
use_ok(qw(ksb::PhaseList));
use_ok(qw(ksb::RecursiveFH));
use_ok(qw(ksb::StatusView));
use_ok(qw(ksb::Updater::Bzr));
use_ok(qw(ksb::Updater::Git));
use_ok(qw(ksb::Updater::KDEProject));
use_ok(qw(ksb::Updater::KDEProjectMetadata));
use_ok(qw(ksb::Updater::Svn));
use_ok(qw(ksb::Updater));
use_ok(qw(ksb::Util));
use_ok(qw(ksb::Version));
use_ok(qw(ksb::l10nSystem));
done_testing();
# Running Tests
These tests require the normal Perl testing harness. It's probably already
included though.
Run from the kdesrc-build base directory (i.e. not in *this* directory), using
the Perl command `prove`, which should be installed along with the
Test::Harness module, if I remember right.
So that kdesrc-build's own modules can be found properly, you need to use the
`-I` flag. So if you're running from the right directory, this command should
work: `prove -Imodules`.
use 5.014;
use Test::More;
use ksb::Application;
my @args = qw(-p --stop-on-failure --resume-from qt --stop-after qt2);
my $app = new_ok('ksb::Application', \@args);
my $ctx = $app->context();
ok($ctx->hasOption('stop-on-failure'), 'stop-on-failure set');
cmp_ok($ctx->getOption('stop-on-failure'), '==', 1, 'stop-on-failure set to 1');
ok($ctx->hasOption('resume-from'), 'resume-from set');
is($ctx->getOption('resume-from'), 'qt', 'resume-from set to qt');
ok($ctx->hasOption('stop-after'), 'stop-after set');
is($ctx->getOption('stop-after'), 'qt2', 'stop-after set to qt2');
done_testing();
use 5.014;
use Test::More;
use ksb::Application;
my @args = qw(-p --run printenv a b);
my $app = new_ok('ksb::Application', \@args);
ok(exists $app->{shell_to_cmd}, '--run shell cmd/args exist');
ok(ref $app->{shell_to_cmd} eq 'ARRAY', '--run shell cmd/args are listref');
is_deeply($app->{shell_to_cmd}, [qw(printenv a b)]);
done_testing();
global
source-dir /tmp
end global
module test1
# should default to SVN on the old anonsvn for now
end module
module test2
repository git://anongit.kde.org/kdesrc-build.git
end module
use 5.018;
use strict;
use warnings;
use Test::More;
use ksb::Application;
my $app = ksb::Application->new(qw(--pretend --rc-file t/data/gen-module-list/kdesrc-buildrc));
my @moduleList = $app->generateModuleList();
ok(@moduleList > 0, 'Multiple modules to build');
done_testing();
use 5.014;
package test {
use Test::More;
push @INC, '.';
require_ok "./kdesrc-build";
done_testing();
};
use 5.014;
use strict;
use warnings;
# https://bugs.kde.org/show_bug.cgi?id=388180
use Test::More;
use Scalar::Util qw(openhandle);
use File::Temp;
use JSON::PP;
use ksb::BuildContext;
my $ctx = new_ok( 'ksb::BuildContext' );
$ctx->setRcFile('/dev/null');
ok(openhandle($ctx->loadRcFile()), 'loadRcFile gives a filehandle');
is($ctx->rcFile(), '/dev/null', 'Roundtrip setRcFile');
is($ctx->persistentOptionFileName(), '/dev/.kdesrc-build-data', 'Default persistent data path');
my $tmp = File::Temp->new (TEMPLATE => 'kdesrc-build-XXXXXX');
$ctx->setOption('persistent-data-file', "$tmp");
is($ctx->persistentOptionFileName(), "$tmp", 'Setting persistent-data-file filename');
unlink("$tmp"); # Simulate missing persistent opts file
$ctx->loadPersistentOptions();
ok(exists $ctx->{persistent_options}, 'loadPersistentOpts sets build context');
is_deeply($ctx->{persistent_options}, {}, 'Persistent opts empty');
$ctx->setPersistentOption('global', 'key', 'value');
is_deeply($ctx->{persistent_options},
{ global => { key => 'value' } },
'Persistent opts set');
$ctx->storePersistentOptions();
SKIP: {
skip 'JSON did not save' unless open my $fh, '<', "$tmp";
my $json_data = do { local $/ = undef; <$fh> }; # slurp mode
ok(defined $json_data, "Read something of JSON data back");
my $persistent_data = decode_json($json_data);
is_deeply($ctx->{persistent_options},
{ global => { key => 'value' } },
'Persistent opts saved');
};
done_testing();
use 5.014;
use strict;
use warnings;
use Test::More import => ['!note'];
use File::Temp qw(tempdir);
use ksb::Application;
use ksb::BuildContext;
my $tmpDir = tempdir(TEMPLATE => 'kdesrc-build-rcXXXXXX', TMPDIR => 1, CLEANUP => 1);
my $rcFile = "$tmpDir/kdesrc-buildrc";
open my $tmp, '>', $rcFile or BAIL_OUT("Can't save to temp file");
print $tmp <<'EOF';
global
git-repository-base qt kde://anongit.kde.org/qt/
my-opt-1 FOO
my-opt-2 BAR
end global
module-set test
repository qt
use-modules 1.git 2.git
make-options MAKE_FOO=${my-opt-1} MAKE_BAR=${my-opt-2}
end module-set
EOF
close $tmp;
my $app = ksb::Application->new('--pretend', '--rc-file', $rcFile);
isa_ok($app, 'ksb::Application');
my $ctx = $app->context();
isa_ok($ctx, 'ksb::BuildContext');
# options already read, ensure we used the rc-file we asked for
is($ctx->rcFile(), $rcFile, "used rc-file $rcFile");
# module sets won't have been expanded yet, read options directly from
# ctx hash
is(ref $app->{rc_mods_sets}, 'ARRAY', 'rc-file read properly into $app');
ok(scalar @{$app->{rc_mods_sets}}, 'list of read modules is not empty');
is($ctx->getOption('my-opt-1', 'module'), 'FOO', 'Global user-defined option imbedded into $ctx');
is($ctx->getOption('my-opt-2', 'module'), 'BAR', 'Global user-defined option imbedded into $ctx');
# grep requires parens around testSet to force list context, otherwise it just
# counts matches
my ($testSet) = grep { $_->name() eq 'test' } (@{$app->{rc_mods_sets}});
isa_ok($testSet, 'ksb::ModuleSet', 'test module is already a ModuleSet');
is($testSet->getOption('make-options', 'module'), 'MAKE_FOO=FOO MAKE_BAR=BAR',
'make-options included previous options');
ok(!$testSet->isa('ksb::ModuleSet::KDEProjects'), 'test set should be a plain module set');
done_testing();