[kdesrc-build/make_it_mojo] /: Merge remote-tracking branch 'gitlab/master' into make_it_mojo

Michael Pyne null at kde.org
Fri Dec 28 03:58:50 GMT 2018


Git commit efc3b42794c91a75e344135b142ba92506717e32 by Michael Pyne.
Committed on 28/12/2018 at 03:37.
Pushed by mpyne into branch 'make_it_mojo'.

Merge remote-tracking branch 'gitlab/master' into make_it_mojo

Mostly a clean merge despite the conflicts, but the test suite showed
that there's still a lot of work to do around cmdline handling with the
mojo-based setup. We can't create a whole web server each time just to
handle --version...

Conflicts:
	CMakeLists.txt
	doc/man-kdesrc-build.1.docbook
	kdesrc-build
	kdesrc-buildrc-sample
	modules/ksb/Application.pm
	modules/ksb/BuildSystem.pm
	modules/ksb/IPC.pm
	modules/ksb/IPC/Pipe.pm
	modules/ksb/Util.pm

M  +2    -1    CMakeLists.txt
M  +20   -2    doc/index.docbook
M  +46   -1    doc/man-kdesrc-build.1.docbook
M  +126  -28   kdesrc-build
M  +63   -97   modules/ksb/Application.pm
M  +3    -0    modules/ksb/BuildContext.pm
M  +54   -0    modules/ksb/BuildException.pm
M  +1    -0    modules/ksb/BuildSystem.pm
M  +1    -0    modules/ksb/BuildSystem/QMake.pm
M  +3    -17   modules/ksb/Module.pm
M  +2    -1    modules/ksb/ModuleResolver.pm
M  +3    -2    modules/ksb/ModuleSet/KDEProjects.pm
M  +1    -0    modules/ksb/Updater/Git.pm
M  +2    -1    modules/ksb/Updater/KDEProjectMetadata.pm
M  +1    -0    modules/ksb/Updater/Svn.pm
A  +1    -1    modules/web/BackendServer.pm
M  +41   -0    t/bug-402509-masked-cmdline-opts.t
M  +89   -0    t/install-and-run.t
M  +3    -3    vim/syntax/kdesrc-buildrc.vim

https://invent.kde.org/kde/kdesrc-build/commit/efc3b42794c91a75e344135b142ba92506717e32

diff --cc CMakeLists.txt
index 1566ec0,7e1c669..8ac976c
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@@ -39,6 -39,8 +39,7 @@@ if (KDESRC_BUILD_INSTALL_MODULES
          modules/ksb/BuildSystem.pm
          modules/ksb/Debug.pm
          modules/ksb/DependencyResolver.pm
+         modules/ksb/FirstRun.pm
 -        modules/ksb/IPC.pm
          modules/ksb/KDEProjectsReader.pm
          modules/ksb/Module.pm
          modules/ksb/ModuleResolver.pm
diff --cc kdesrc-build
index a4cc72a,5149c0c..f555f8e
--- a/kdesrc-build
+++ b/kdesrc-build
@@@ -39,22 -36,114 +36,124 @@@ use 5.014; # Require Perl 5.1
  use strict;
  use warnings;
  
- use Carp;
- use Data::Dumper;
- use File::Find; # For our lndir reimplementation.
- use File::Path qw(remove_tree);
+ # On many container-based distros, even FindBin is missing to conserve space.
+ # But we can use File::Spec to do nearly the same.
+ my $RealBin;
+ my $modPath;
+ 
+ # The File::Spec calls have to run when parsing (i.e. in BEGIN) to make the
+ # 'use lib' below work (which itself implicitly uses BEGIN { })
+ BEGIN {
+     use File::Spec;
+ 
+     # resolve symlinks
+     my $scriptPath = $0;
+     for (1..16) {
+         last unless -l $scriptPath;
+         $scriptPath = readlink $scriptPath;
+     }
+     die "Too many symlinks followed looking for script" if -l $scriptPath;
  
- use Mojo::IOLoop;
- use Mojo::Server::Daemon;
+     my ($volume, $directories, $script) = File::Spec->splitpath($scriptPath);
  
- use ksb::Debug;
- use ksb::Util;
- use ksb::Version qw(scriptVersion);
- use ksb::Application;
- use ksb::UserInterface::TTY;
- use web::BackendServer;
+     $RealBin = File::Spec->catpath($volume, $directories, '');
+     die "Couldn't find base directory!" unless $RealBin;
  
- use 5.014; # Require Perl 5.14
+     # Use modules in git repo if running from git dir, otherwise assume
+     # system install
+     $modPath = File::Spec->rel2abs('modules', $RealBin);
+     $modPath = ($RealBin =~ s,/bin/?$,/share/kdesrc-build/modules,r)
+         unless -d $modPath;
+ 
+     die "Couldn't find modules for kdesrc-build!" unless $modPath;
+ }
+ 
+ use lib "$modPath"; # Make ksb:: modules available
+ 
+ sub dumpError
+ {
+     my $err = $@;
+     open my $fh, '>>', "error-$$.log" or return;
+     my $time = localtime;
+     say $fh $time;
+     say $fh $@;
+ }
+ 
+ # When running in a limited environment, we might not be able to load
+ # our modules although we can find them. In this case we should help user
+ # by setting up system dependencies.
+ eval {
+     if (grep { $_ eq '--initial-setup' } @ARGV) {
+         require ksb::FirstRun;
+         require ksb::Debug;
+         ksb::Debug::setColorfulOutput(1);
+         exit ksb::FirstRun::setupUserSystem($RealBin);
+     }
+ };
+ 
+ if ($@) {
+     dumpError();
+     say STDERR <<DONE;
+ * Unable to even load the simplistic initial setup support for some reason??
+ 
+ More detail might be available in error-$$.log
+ 
+ You could:
+  File a bug https://bugs.kde.org/enter_bug.cgi?product=kdesrc-build
+  Ask for help on Freenode IRC in the #kde channel
+ DONE
+     exit 1;
+ }
+ 
+ # Even though the flow of execution should not make it here unless the modules
+ # we need are installed, we still cannot "use" the modules that might be
+ # missing on first use since just trying to parse/compile the code is then
+ # enough to cause errors.
+ eval {
+     use Carp;
+     use File::Find; # For our lndir reimplementation.
+     use File::Path qw(remove_tree);
+ 
+     require ksb::Debug;
+     require ksb::Util;
+     require ksb::Version;
+     require ksb::Application;
+     require ksb::BuildException;
++    require ksb::UserInterface::TTY;
++    require web::BackendServer;
++
++    require Mojo::IOLoop;
++    require Mojo::Server::Daemon;
+ };
+ 
+ if ($@) {
+     dumpError();
+     say STDERR <<DONE;
+ Couldn't load the base platform for kdesrc-build!
+ More detail might be available in error-$$.log
+ DONE
+ 
+     if (! -e "kdesrc-buildrc" && ! -e "$ENV{HOME}/.kdesrc-buildrc") {
+         say STDERR <<DONE;
+ It appears you've not run kdesrc-build before.
+ 
+ Please run "kdesrc-build --initial-setup" and kdesrc-build will guide you
+ through setting up required dependencies and environment setup.
+ DONE
+     }
+     exit 1;
+ }
+ 
+ ksb::Debug->import();
+ ksb::Util->import();
+ ksb::BuildException->import();
+ ksb::Version->import(qw(scriptVersion));
+ ksb::Application->import();
++ksb::UserInterface::TTY->import();
++web::BackendServer->import();
++
++Mojo::IOLoop->import();
++Mojo::Server::Daemon->import();
  
  # Make Perl 'plain die' exceptions use Carp::confess instead of their core
  # support. This is not supported by the Perl 5 authors but assuming it works
@@@ -288,41 -358,16 +390,37 @@@ END 
      }
  }
  
++# TODO: Need to split up option reading here to exit early for some options
++# (--help, --version, etc) and only continue on with creating a U/I if there's
++# then still work to do. But this still needs to follow reading the rc-file!
++# Until fixed this will fail t/install-and-run.t (which will handle --version in
++# ui->start() and then as an atexit handler app->ksb->finish)
++
  # Use some exception handling to avoid ucky error messages
  eval
  {
 -    $app = ksb::Application->new(@ARGV);
 +    my $app = web::BackendServer->new(@ARGV);
 +    my $ui  = ksb::UserInterface::TTY->new($app);
 +
-     # Hack for debugging current state.
-     if (exists $ENV{KDESRC_BUILD_DUMP_CONTEXT}) {
-         local $Data::Dumper::Indent = 1;
-         local $Data::Dumper::Sortkeys = 1;
- 
-         # This method call dumps the first list with the variables named by the
-         # second list.
-         print Data::Dumper->Dump([$app->ksb->context()], [qw(ctx)]);
-     }
- 
 +    push @atexit_subs, sub { $app->ksb->finish(99) };
  
 -    push @atexit_subs, sub { $app->finish(99) };
 -    my $result = $app->runAllModulePhases();
 +    # TODO: Reimplement --print-modules, --query modes, which wouldn't go through ->start
 +    my $result = $ui->start();
  
      @atexit_subs = (); # Clear exit handlers
 -    $app->finish($result);
 +
 +    # env driver is just the ~/.config/kde-env-*.sh, session driver is that + ~/.xsession
 +    my $ctx = $app->context;
 +    if ($ctx->getOption('install-environment-driver') ||
 +        $ctx->getOption('install-session-driver'))
 +    {
 +        ksb::Application::_installCustomSessionDriver($ctx);
 +    }
 +
 +    # Exits the script
 +    my $logdir = $app->context()->getLogDir();
 +    note ("Your logs are saved in y[$logdir]");
 +    exit $result;
  };
  
  if (my $err = $@)
diff --cc modules/ksb/Application.pm
index d77e238,ee3db10..a9c6e56
--- a/modules/ksb/Application.pm
+++ b/modules/ksb/Application.pm
@@@ -281,18 -285,19 +287,20 @@@ DON
  
      # Actually read the options.
      my $optsSuccess = GetOptionsFromArray(\@options, \%foundOptions,
-         'version', 'author', 'help', 'show-info', 'disable-snapshots|no-snapshots',
+         # Options here should not duplicate the flags and options defined below
+         # from ksb::BuildContext!
+         'version|v', 'author', 'help', 'show-info', 'initial-setup',
          'install', 'uninstall', 'no-src|no-svn', 'no-install', 'no-build',
          'no-tests', 'build-when-unchanged|force-build', 'no-metadata',
-         'verbose|v', 'quiet|quite|q', 'really-quiet', 'debug',
+         'verbose', 'quiet|quite|q', 'really-quiet', 'debug',
 -        'reconfigure', 'colorful-output|color!', 'async!',
 +        'reconfigure', 'colorful-output|color!',
          'src-only|svn-only', 'build-only', 'install-only', 'build-system-only',
          'rc-file=s', 'prefix=s', 'niceness|nice:10', 'ignore-modules=s{,}',
          'print-modules', 'pretend|dry-run|p', 'refresh-build',
          'query=s', 'start-program|run=s{,}',
 +        'launch-browser',
          'revision=i', 'resume-from=s', 'resume-after=s',
-         'rebuild-failures', 'resume', 'stop-on-failure',
+         'rebuild-failures', 'resume',
          'stop-after=s', 'stop-before=s', 'set-module-option-value=s',
          'metadata-only', 'include-dependencies',
  
@@@ -448,39 -450,19 +456,35 @@@ sub establishContex
      $moduleResolver->setInputModulesAndOptions(\@optionModulesAndSets);
      $moduleResolver->setIgnoredSelectors([keys %ignoredSelectors]);
  
 -    $self->_defineNewModuleFactory($moduleResolver);
 +    return @selectors;
 +}
 +
 +# Requires establishContext to have been called first. Converts string-based
 +# "selectors" for modules or module-sets into a list of ksb::Modules (only
 +# modules, no sets).
 +#
 +# After this function is called all module set selectors will have been
 +# expanded, and we will have downloaded kde-projects metadata.
 +#
- # The modules returns must still be added (using setModulesToProcess) to the
++# The modules returned must still be added (using setModulesToProcess) to the
 +# context if you intend to build. This is a separate step to allow for some
 +# introspection prior to making choice to build.
 +#
 +# Returns: List of Modules to build.
 +sub modulesFromSelectors
 +{
 +    my ($self, @selectors) = @_;
 +    my $moduleResolver = $self->{module_resolver};
 +    my $ctx = $self->context();
  
      my @modules;
 -    if ($commandLineModules) {
 +    if (@selectors) {
          @modules = $moduleResolver->resolveSelectorsIntoModules(@selectors);
- 
-         ksb::Module->setModuleSource('cmdline');
      }
      else {
          # Build everything in the rc-file, in the order specified.
 -        @modules = $moduleResolver->expandModuleSets(@optionModulesAndSets);
 -
 -        if ($ctx->getOption('kde-languages')) {
 -            @modules = _expandl10nModules($ctx, @modules);
 -        }
 +        my @rcfileModules = @{$moduleResolver->{inputModulesAndOptions}};
 +        @modules = $moduleResolver->expandModuleSets(@rcfileModules);
- 
-         ksb::Module->setModuleSource('config');
      }
  
      # If modules were on the command line then they are effectively forced to
diff --cc modules/ksb/BuildException.pm
index f55dd9a,be4d6ff..b0479d4
--- a/modules/ksb/BuildException.pm
+++ b/modules/ksb/BuildException.pm
@@@ -37,6 -41,55 +41,56 @@@ sub setMessag
      $self->{message} = $newMessage;
  }
  
+ #
+ # Exported utility functions
+ #
+ 
+ # Returns a Perl exception object to pass to 'die' function
+ # The returned reference will be an instance of ksb::BuildException.
+ #
+ # First parameter: Exception type, 'Exception' if undef
+ # Second parameter: Message to show to user
+ sub make_exception
+ {
+     my $exception_type = shift // 'Exception';
+     my $message = shift;
+     my $levels = shift // 0; # Allow for more levels to be removed from bt
+ 
+     # Remove this subroutine from the backtrace
+     local $Carp::CarpLevel = 1 + $levels;
+ 
 -    $message = Carp::cluck($message) if $exception_type eq 'Internal';
++    $message = Carp::longmess($message)
++        if $exception_type eq 'Internal';
+     return ksb::BuildException->new($exception_type, $message);
+ }
+ 
+ # Helper function to return $@ if $@ is a ksb::BuildException.
+ #
+ # This function assumes that an eval block had just been used in order to set
+ # or clear $@ as appropriate.
+ sub had_an_exception
+ {
+     if ($@ && ref $@ && $@->isa('ksb::BuildException')) {
+         return $@;
+     }
+ 
+     return;
+ }
+ 
+ # Should be used for "runtime errors" (i.e. unrecoverable runtime problems that
+ # don't indicate a bug in the program itself).
+ sub croak_runtime
+ {
+     die (make_exception('Runtime', $_[0], 1));
+ }
+ 
+ # Should be used for "logic errors" (i.e. impossibilities in program state, things
+ # that shouldn't be possible no matter what input is fed at runtime)
+ sub croak_internal
+ {
+     die (make_exception('Internal', $_[0], 1));
+ }
+ 
  #
  # A small subclass to hold the option name that caused a config exception to
  # be thrown.
diff --cc modules/ksb/BuildSystem.pm
index dae89dc,2053f3b..548166a
--- a/modules/ksb/BuildSystem.pm
+++ b/modules/ksb/BuildSystem.pm
@@@ -8,7 -8,8 +8,8 @@@ use strict
  use warnings;
  use 5.014;
  
+ use ksb::BuildException;
 -use ksb::Debug;
 +use ksb::Debug 0.30;
  use ksb::Util;
  use ksb::StatusView;
  
diff --cc modules/ksb/Updater/Git.pm
index de20ff0,7d8fb67..7de3188
--- a/modules/ksb/Updater/Git.pm
+++ b/modules/ksb/Updater/Git.pm
@@@ -10,7 -10,9 +10,8 @@@ use 5.014
  
  use parent qw(ksb::Updater);
  
+ use ksb::BuildException;
  use ksb::Debug;
 -use ksb::IPC::Null;
  use ksb::Util;
  
  use File::Basename; # basename
diff --cc modules/ksb/Updater/KDEProjectMetadata.pm
index 396dcac,bcb3c63..2670bb0
--- a/modules/ksb/Updater/KDEProjectMetadata.pm
+++ b/modules/ksb/Updater/KDEProjectMetadata.pm
@@@ -9,10 -9,11 +9,11 @@@ use 5.014
  
  use parent qw(ksb::Updater::KDEProject);
  
- use ksb::Util;
+ use ksb::BuildException;
  use ksb::Debug;
+ use ksb::Util;
  
 -use JSON::PP;
 +use Mojo::JSON qw(decode_json);
  
  sub name
  {
diff --cc modules/web/BackendServer.pm
index 4a56c23,0000000..bf76d6e
mode 100644,000000..100644
--- a/modules/web/BackendServer.pm
+++ b/modules/web/BackendServer.pm
@@@ -1,259 -1,0 +1,259 @@@
 +package web::BackendServer;
 +
 +# Make this subclass a Mojolicious app
 +use Mojo::Base 'Mojolicious';
 +use Mojo::Util qw(trim);
 +
 +use ksb::Application;
 +
 +use Cwd;
 +
 +# This is written in a kind of domain-specific language for Mojolicious for
 +# now, to setup a web server backend for clients / frontends to communicate
 +# with.
 +# See https://mojolicious.org/perldoc/Mojolicious/Guides/Tutorial
 +
 +has 'options';
 +has 'selectors';
 +
 +sub new
 +{
 +    my ($class, @opts) = @_;
 +    return $class->SUPER::new(options => [@opts], ksbhome => getcwd());
 +}
 +
 +# Adds a helper method to each HTTP context object to return the
 +# ksb::Application class in use
 +sub make_new_ksb
 +{
 +    my $c = shift;
 +
 +    # ksb::Application startup uses current dir to find right rc-file
 +    # by default.
 +    chdir($c->app->{ksbhome});
 +    my $app = ksb::Application->new->setHeadless;
 +
 +    my @selectors = $app->establishContext(@{$c->app->{options}});
 +    $c->app->selectors([@selectors]);
 +    $c->app->log->info("Selectors are ", join(', ', @selectors));
 +
 +    return $app;
 +}
 +
 +# Package-shared variables for helpers and closures
 +my $LAST_RESULT;
 +my $BUILD_PROMISE;
 +my $IN_PROGRESS;
 +my $KSB_APP;
 +
 +sub startup {
 +    my $self = shift;
 +
 +    # Force use of 'modules/web' as the home directory, would normally be
 +    # 'modules' alone
 +    $self->home($self->home->child('web'));
 +
 +    # Fixup templates and public base directories
 +    $self->static->paths->[0]   = $self->home->child('public');
 +    $self->renderer->paths->[0] = $self->home->child('templates');
 +
 +    $self->helper(ksb => sub {
 +        my ($c, $new_ksb) = @_;
 +
-         $KSB_APP //= make_new_ksb($c);
 +        $KSB_APP = $new_ksb if $new_ksb;
++        $KSB_APP //= make_new_ksb($c);
 +
 +        return $KSB_APP;
 +    });
 +
 +    $self->helper(in_build => sub { $IN_PROGRESS });
 +    $self->helper(context  => sub { shift->ksb->context() });
 +
 +    my $r = $self->routes;
 +    $self->_generateRoutes;
 +
 +    return;
 +}
 +
 +sub _generateRoutes {
 +    my $self = shift;
 +    my $r = $self->routes;
 +
 +    $r->get('/' => 'index');
 +
 +    $r->post('/reset' => sub {
 +        my $c = shift;
 +
 +        if ($c->in_build || !defined $LAST_RESULT) {
 +            $c->res->code(400);
 +            return $c->render;
 +        }
 +
 +        my $old_result = $LAST_RESULT;
 +        $c->ksb(make_new_ksb($c));
 +        undef $LAST_RESULT;
 +
 +        $c->render(json => { last_result => $old_result });
 +    });
 +
 +    $r->get('/context/options' => sub {
 +        my $c = shift;
 +        $c->render(json => $c->ksb->context()->{options});
 +    });
 +
 +    $r->get('/context/options/:option' => sub {
 +        my $c = shift;
 +        my $ctx = $c->ksb->context();
 +
 +        my $opt = $c->param('option') or do {
 +            $c->res->code(400);
 +            return $c->render;
 +        };
 +
 +        if (defined $ctx->{options}->{$opt}) {
 +            $c->render(json => { $opt => $ctx->{options}->{$opt} });
 +        }
 +        else {
 +            $c->res->code(404);
 +            $c->reply->not_found;
 +        }
 +    });
 +
 +    $r->get('/modules' => sub {
 +        my $c = shift;
 +        $c->render(json => $c->ksb->context()->moduleList());
 +    } => 'module_lookup');
 +
 +    $r->get('/known_modules' => sub {
 +        my $c = shift;
 +        my $resolver = $c->ksb->{module_resolver};
 +        my @setsAndModules = @{$resolver->{inputModulesAndOptions}};
 +        my @output = map {
 +            $_->isa('ksb::ModuleSet')
 +                ? [ $_->name(), $_->moduleNamesToFind() ]
 +                : $_->name() # should be a ksb::Module
 +        } @setsAndModules;
 +
 +        $c->render(json => \@output);
 +    });
 +
 +    $r->post('/modules' => sub {
 +        my $c = shift;
 +        my $selectorList = $c->req->json;
 +        my $build_all = $c->req->headers->header('X-BuildAllModules');
 +
 +        # Remove empty selectors
 +        my @modules = grep { !!$_ } map { trim($_ // '') } @{$selectorList};
 +
 +        # If not building all then ensure there's at least one module to build
 +        if ($c->in_build || !$selectorList || (!@modules && !$build_all) || (@modules && $build_all)) {
 +            $c->app->log->error("Something was wrong with modules to assign to build");
 +            return $c->render(text => "Invalid request sent", status => 400);
 +        }
 +
 +        eval {
 +            @modules = $c->ksb->modulesFromSelectors(@modules);
 +            $c->ksb->setModulesToProcess(@modules);
 +        };
 +
 +        if ($@) {
 +            return $c->render(text => $@->{message}, status => 400);
 +        }
 +
 +        my $numSels = @modules; # count
 +
 +        $c->render(json => ["$numSels handled"]);
 +    }, 'post_modules');
 +
 +    $r->get('/module/:modname' => sub {
 +        my $c = shift;
 +        my $name = $c->stash('modname');
 +
 +        my $module = $c->ksb->context()->lookupModule($name);
 +        if (!$module) {
 +            $c->render(template => 'does_not_exist');
 +            return;
 +        }
 +
 +        my $opts = {
 +            options => $module->{options},
 +            persistent => $c->ksb->context()->{persistent_options}->{$name},
 +        };
 +        $c->render(json => $opts);
 +    });
 +
 +    $r->get('/module/:modname/logs/error' => sub {
 +        my $c = shift;
 +        my $name = $c->stash('modname');
 +        $c->render(text => "TODO: Error logs for $name");
 +    });
 +
 +    $r->get('/config' => sub {
 +        my $c = shift;
 +        $c->render(text => $c->ksb->context()->rcFile());
 +    });
 +
 +    $r->post('/config' => sub {
 +        # TODO If new filename can be loaded, load it and reset application object
 +        die "Unimplemented";
 +    });
 +
 +    $r->get('/build-metadata' => sub {
 +        die "Unimplemented";
 +    });
 +
 +    $r->websocket('/events' => sub {
 +        my $c = shift;
 +
 +        $c->inactivity_timeout(0);
 +
 +        my $ctx = $c->ksb->context();
 +        my $monitor = $ctx->statusMonitor();
 +
 +        # Send prior events the receiver wouldn't have received yet
 +        my @curEvents = $monitor->events();
 +        $c->send({json => \@curEvents});
 +
 +        # Hook up an event handler to send future events as they're generated
 +        $monitor->on(newEvent => sub {
 +            my ($monitor, $resultRef) = @_;
 +            $c->on(drain => sub { $c->finish })
 +                if ($resultRef->{event} eq 'build_done');
 +            $c->send({json => [ $resultRef ]});
 +        });
 +    });
 +
 +    $r->get('/event_viewer' => sub {
 +        my $c = shift;
 +        $c->render(template => 'event_viewer');
 +    });
 +
 +    $r->get('/building' => sub {
 +        my $c = shift;
 +        $c->render(text => $c->in_build ? 'True' : 'False');
 +    });
 +
 +    $r->post('/build' => sub {
 +        my $c = shift;
 +        if ($c->in_build) {
 +            $c->res->code(400);
 +            $c->render(text => 'Build already in progress, cancel it first.');
 +            return;
 +        }
 +
 +        $c->app->log->debug('Starting build');
 +
 +        $IN_PROGRESS = 1;
 +
 +        $BUILD_PROMISE = $c->ksb->startHeadlessBuild->finally(sub {
 +            my ($result) = @_;
 +            $c->app->log->debug("Build done");
 +            $IN_PROGRESS = 0;
 +            return $LAST_RESULT = $result;
 +        });
 +
 +        $c->render(text => $c->url_for('event_viewer')->to_abs->to_string);
 +    });
 +}
 +
 +1;
diff --cc t/bug-402509-masked-cmdline-opts.t
index 0000000,f7e3951..0d71ed3
mode 000000,100644..100644
--- a/t/bug-402509-masked-cmdline-opts.t
+++ b/t/bug-402509-masked-cmdline-opts.t
@@@ -1,0 -1,39 +1,41 @@@
+ use 5.014;
+ use strict;
+ use warnings;
+ 
+ # Checks that we don't inadvertently eat non-option
+ # arguments in cmdline processing, which happened with
+ # some cmdline options that were inadvertently handled
+ # both directly in _readCommandLineOptionsAndSelectors
+ # and indirectly via being in
+ # ksb::BuildContext::defaultGlobalFlags)
+ # See bug 402509 -- https://bugs.kde.org/show_bug.cgi?id=402509
+ 
+ use Test::More;
+ 
+ use ksb::Application;
+ use ksb::Module;
+ 
+ # This bug had affected --stop-on-failure and --disable-snapshots
+ my @args = qw(--pretend --rc-file t/data/sample-rc/kdesrc-buildrc --stop-on-failure setmod3);
+ 
+ {
 -    my $app = ksb::Application->new(@args);
 -    my @moduleList = @{$app->{modules}};
++    my $app = ksb::Application->new(@args)->setHeadless;
++    my @selectors = $app->establishContext(@args);
++    my @moduleList = $app->modulesFromSelectors(@selectors);
+ 
+     is (scalar @moduleList, 1, 'Right number of modules (just one)');
 -    is ($moduleList[0]->name(), 'setmod3', 'mod list[2] == setmod3');
++    is ($moduleList[0]->name(), 'setmod3', 'mod list[0] == setmod3');
+ }
+ 
+ $args[-2] = '--disable-snapshots';
+ 
+ {
 -    my $app = ksb::Application->new(@args);
 -    my @moduleList = @{$app->{modules}};
++    my $app = ksb::Application->new(@args)->setHeadless;
++    my @selectors = $app->establishContext(@args);
++    my @moduleList = $app->modulesFromSelectors(@selectors);
+ 
+     is (scalar @moduleList, 1, 'Right number of modules (just one)');
 -    is ($moduleList[0]->name(), 'setmod3', 'mod list[2] == setmod3');
++    is ($moduleList[0]->name(), 'setmod3', 'mod list[0] == setmod3');
+ }
+ 
+ done_testing();
diff --cc t/install-and-run.t
index 0000000,0450c00..3992d33
mode 000000,100644..100644
--- a/t/install-and-run.t
+++ b/t/install-and-run.t
@@@ -1,0 -1,83 +1,89 @@@
+ use 5.014;
+ use strict;
+ use warnings;
+ 
+ # Test install and ability to run a simple status command w/out Perl failures
+ 
+ use Test::More;
+ use Cwd;
+ use IPC::Cmd;
+ 
+ # Assume we're running directly for git source root, as required for rest of
+ # test suite.
+ 
+ ok(-d "t", 'Test directory in right spot');
+ ok(-f "kdesrc-build", 'kdesrc-build script in right spot');
+ 
+ # This test can't pass from an installed kdesrc-build, unless user goes out of
+ # their way to move files around or establish a broken module layout. If this
+ # passes, we should be able to assume we're running from a git source dir
+ ok(-f "modules/ksb/Version.pm", 'kdesrc-build modules found in git-src');
+ 
+ # Make sure kdesrc-build can still at least start when run directly
+ my $result = system('./kdesrc-build', '--version', '--pretend');
+ is($result >> 8, 0, 'Direct-run kdesrc-build works');
+ 
+ use File::Temp ();
+ 
+ Test::More::note('Installing kdesrc-build to simulate running from install-dir');
+ 
+ my $tempInstallDir = File::Temp->newdir();
+ mkdir ("$tempInstallDir/bin") or die "Couldn't make fake bin dir! $!";
+ 
+ my $curdir = getcwd();
+ symlink("$curdir/kdesrc-build", "$tempInstallDir/bin/kdesrc-build");
+ 
+ # Ensure a direct symlink to the source directory of kdesrc-build still works
+ {
+     local $ENV{PATH} = "$tempInstallDir/bin:" . $ENV{PATH};
+ 
+     my $output = `kdesrc-build --version --pretend`;
 -    ok($output =~ /^kdesrc-build \d\d\.\d\d \(v\d\d/, '--version for git-based version is appropriate');
++    TODO: {
++        local $TODO = '--version output duplicated, see ../kdesrc-build TODO';
++        ok($output =~ /^kdesrc-build \d\d\.\d\d \(v\d\d/, '--version for git-based version is appropriate');
++    };
+ 
+     die "kdesrc-build is supposed to be a symlink! $!"
+         unless -l "$tempInstallDir/bin/kdesrc-build";
+     die "Couldn't remove kdesrc-build symlink, will conflict with install! $!"
+         unless unlink ("$tempInstallDir/bin/kdesrc-build");
+ }
+ 
+ # Ensure the installed version also works.
+ # TODO: Use manipulation on installed ksb::Version to ensure we're seeing right
+ # output?
+ {
+     my $tempBuildDir = File::Temp->newdir();
+     chdir ("$tempBuildDir") or die "Can't cd to build dir $!";
+ 
+     # Use IPC::Cmd to capture (and ignore) output. All we need is the exit code
+     my ($buildResult, $errMsg) = IPC::Cmd::run(
+ 	command => [
+ 	    'cmake', "-DCMAKE_INSTALL_PREFIX=$tempInstallDir", "-DBUILD_doc=OFF", $curdir
+ 	],
+ 	verbose => 0,
+ 	timeout => 60);
+     die "Couldn't run cmake! $errMsg"
+         unless $buildResult;
+ 
+     $buildResult = system ('make');
+     die "Couldn't run make! $buildResult"
+         if ($buildResult == -1 || ($buildResult >> 8) != 0);
+ 
+     $buildResult = system ('make install');
+     die "Couldn't install! $buildResult"
+         if ($buildResult == -1 || ($buildResult >> 8) != 0);
+ 
+     # Ensure newly-installed version is first in PATH
+     local $ENV{PATH} = "$tempInstallDir/bin:" . $ENV{PATH};
+ 
+     my $output = `kdesrc-build --version --pretend`;
 -    ok($output =~ /^kdesrc-build \d\d\.\d\d\n?$/, '--version for installed version is appropriate');
++    TODO: {
++        local $TODO = '--version output duplicated, see ../kdesrc-build TODO';
++        ok($output =~ /^kdesrc-build \d\d\.\d\d\n?$/, '--version for installed version is appropriate');
++    };
+ 
+     chdir($curdir);
+ }
+ 
+ done_testing();


More information about the kde-doc-english mailing list