[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kdesrc-build/make_it_mojo] modules/ksb: mojo: Make the Module build routine return a promise.
From:       Michael Pyne <null () kde ! org>
Date:       2018-03-31 20:20:19
Message-ID: E1f2Mz5-0002Co-Hd () code ! kde ! org
[Download RAW message or body]

Git commit 323f6caab70adec7e4300fc50c7bde4e56036521 by Michael Pyne.
Committed on 31/03/2018 at 01:17.
Pushed by mpyne into branch 'make_it_mojo'.

mojo: Make the Module build routine return a promise.

Eventually I want to get to a "log_command_p" kind of construct where
most of the code is aware of promises and only log_command_p uses
subprocesses.

M  +15   -29   modules/ksb/Application.pm
M  +61   -31   modules/ksb/Module.pm

https://commits.kde.org/kdesrc-build/323f6caab70adec7e4300fc50c7bde4e56036521

diff --git a/modules/ksb/Application.pm b/modules/ksb/Application.pm
index cade22b..00a67d6 100644
--- a/modules/ksb/Application.pm
+++ b/modules/ksb/Application.pm
@@ -1389,40 +1389,26 @@ sub _buildSingleModule
     my ($ctx, $module, $startTimeRef) = @_;
 
     $$startTimeRef = time;
-    my $build_promise = Mojo::Promise->new;
+    my $build_promise = $module->build();
 
     my $fail_count = $module->getPersistentOption('failure-count') // 0;
 
-    Mojo::IOLoop->subprocess(
-        sub {
-            # called in child process, can block
-            $SIG{INT} = sub { POSIX::_exit(EINTR); };
-            $0 = 'kdesrc-build-builder';
-
-            $ctx->resetEnvironment();
-            $module->setupEnvironment();
-
-            return $module->build();
-        },
-        sub {
-            # called in this process, with results
-            # in this case the only result is whether there's an error or not
-            my ($subprocess, $err, $was_successful) = @_;
-
-            $fail_count = $was_successful ? 0 : $fail_count + 1;
+    # TODO: Move the elapsed timer stuff in here?
+    my $promise = $build_promise
+        ->catch(sub {
+            my $err = shift;
+
+            # build failed
+            $err //= 'Unknown reason (kdesrc-build bug)';
+            error ("\tr[b[$module] failed to build: $err");
+            $fail_count++;
+        })->then(sub {
+            $fail_count = 0;
+        })->finally(sub {
             $module->setPersistentOption('failure-count', $fail_count);
+        });
 
-            if ($was_successful && !$err) {
-                $build_promise->resolve($module);
-            }
-            else {
-                error ("Failed to build $module due to $err") if $err;
-                $build_promise->reject('build');
-            }
-        }
-    );
-
-    return $build_promise;
+    return $promise;
 }
 
 # Returns undef if build should proceed, otherwise a Promise that will resolve
diff --git a/modules/ksb/Module.pm b/modules/ksb/Module.pm
index c06213d..5ad151f 100644
--- a/modules/ksb/Module.pm
+++ b/modules/ksb/Module.pm
@@ -34,6 +34,10 @@ use ksb::BuildSystem::CMakeBootstrap;
 
 use ksb::ModuleSet::Null;
 
+use Mojo::Promise;
+use Mojo::IOLoop;
+
+use POSIX qw(_exit :errno_h);
 use Storable 'dclone';
 use Carp 'confess';
 use Scalar::Util 'blessed';
@@ -397,7 +401,8 @@ sub buildSystemType
 }
 
 # Subroutine to build this module.
-# Returns boolean false on failure, boolean true on success.
+# Returns a promise that resolves to true (on success) or rejects with a error
+# string
 sub build
 {
     my $self = assert_isa(shift, 'ksb::Module');
@@ -406,43 +411,68 @@ sub build
     my $builddir = $pathinfo{'fullpath'};
     my $buildSystem = $self->buildSystem();
 
-    if ($buildSystem->name() eq 'generic' && !pretending()) {
-        error ("\tr[b[$self] does not seem to have a build system to use.");
-        return 0;
-    }
+    return Mojo::Promise->new->reject('There is no build system to use')
+        if ($buildSystem->name() eq 'generic' && !pretending());
 
     # Ensure we're in a known directory before we start; some options remove
     # the old build directory that a previous module might have been using.
     super_mkdir($pathinfo{'path'});
     p_chdir($pathinfo{'path'});
 
-    return 0 if !$self->setupBuildSystem();
-    return 1 if $self->getOption('build-system-only');
-
-    if (!$buildSystem->buildInternal())
-    {
-        return 0;
-    }
-
-    $self->setPersistentOption('last-build-rev', $self->currentScmRevision());
-
-    # TODO: This should be a simple phase to run.
-    if ($self->getOption('run-tests'))
-    {
-        $self->buildSystem()->runTestsuite();
-    }
-
-    # TODO: Likewise this should be a phase to run.
-    if ($self->getOption('install-after-build'))
-    {
-        return 0 if !$self->install();
-    }
-    else
-    {
-        info ("\tSkipping install for y[$self]");
-    }
+    # TODO: Turn this into a promise too
+    return Mojo::Promise->new->reject('Unable to setup build system')
+        if !$self->setupBuildSystem();
+    return Mojo::Promise->new->resolve
+        if $self->getOption('build-system-only');
+
+    my $promise = Mojo::Promise->new;
+    Mojo::IOLoop->subprocess(
+        sub {
+            # called in child process, can block
+            $SIG{INT} = sub { POSIX::_exit(EINTR); };
+            $0 = 'kdesrc-build-builder';
+
+            $self->buildContext->resetEnvironment();
+            $self->setupEnvironment();
+
+            return 0 if !$buildSystem->buildInternal();
+
+            # TODO: This should be a simple phase to run.
+            if ($self->getOption('run-tests'))
+            {
+                $self->buildSystem()->runTestsuite();
+            }
+
+            # TODO: Likewise this should be a phase to run.
+            if ($self->getOption('install-after-build'))
+            {
+                return 0 if !$self->install();
+            }
+            else
+            {
+                info ("\tSkipping install for y[$self]");
+            }
+
+            return 1; # Success
+        },
+        sub {
+            # called in this process, with results
+            my ($subprocess, $err, $was_successful) = @_;
+            $self->setPersistentOption('last-build-rev', $self->currentScmRevision());
+
+            if ($err) {
+                $promise->reject($err);
+            } elsif ($was_successful) {
+                $promise->resolve(1);
+            } else {
+                $promise->reject('Build failed');
+            }
+
+            return $promise;
+        }
+    );
 
-    return 1;
+    return $promise;
 }
 
 # Subroutine to setup the build system in a directory.

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic