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

Michael Pyne null at kde.org
Sun Feb 14 02:20:58 GMT 2021


Git commit 136fdcdf3c918f94a334e9ca494bb8a3d07aead2 by Michael Pyne.
Committed on 14/02/2021 at 02:18.
Pushed by mpyne into branch 'make_it_mojo'.

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

Still passes revised test suite.

Conflicts:
	modules/ksb/Application.pm
	modules/ksb/BuildSystem/CMake.pm

M  +1    -1    README.md
M  +67   -11   doc/index.docbook
M  +1    -1    doc/man-kdesrc-build.1.docbook
M  +17   -11   modules/ksb/Application.pm
M  +3    -1    modules/ksb/BuildContext.pm
R  +35   -2    modules/ksb/BuildSystem/CMake.pm
M  +141  -7    modules/ksb/FirstRun.pm
M  +44   -3    modules/ksb/Module.pm
M  +76   -0    t/smoke/issue-64-cmdline-opt-override.t
M  +6    -5    t/smoke/read-module-options.t
M  +18   -0    t/unit/build-environment/platform-env-prepend.t
M  +5    -4    vim/syntax/kdesrc-buildrc.vim

https://invent.kde.org/sdk/kdesrc-build/commit/136fdcdf3c918f94a334e9ca494bb8a3d07aead2

diff --cc modules/ksb/Application.pm
index 41ae4c4,e0dc14f..f7563bc
--- a/modules/ksb/Application.pm
+++ b/modules/ksb/Application.pm
@@@ -29,10 -29,9 +29,11 @@@ use ksb::DependencyResolver 0.20
  use ksb::Updater::Git;
  use ksb::Version qw(scriptVersion);
  
 +use Mojo::IOLoop;
 +use Mojo::Promise;
 +
 +use Fcntl; # For sysopen
+ use Scalar::Util qw(blessed);
  use List::Util qw(first min);
  use File::Basename; # basename, dirname
  use File::Glob ':glob';
@@@ -397,247 -370,116 +398,247 @@@ sub _findMissingModule
      return @missingModules;
  }
  
 -sub _yieldModuleDependencyTreeEntry
 +# Method: _handleEarlyOptions
 +#
 +# Uses the user-requested options (as returned by
 +# readCommandLineOptionsAndSelectors) and handles any options that can be
 +# handled without launching the backend or reading the configuration file, and
 +# which would cause the script to exit, such as --help.
 +#
 +# This function may exit entirely for some options, and since the rc-file has
 +# not been read yet, does not handle all possible cases where an early exit is
 +# required. For that, see handleQueryOptions.
 +#
 +# Phase:
 +#  initialization - Do not call <finish> from this function.
 +#
 +# Parameters:
 +#  optsAndSelectors - As from readCommandLineOptionsAndSelectors
 +#
 +# Returns:
 +#  There is no return value. The function may not return at all, and exit instead.
 +sub _handleEarlyOptions
  {
 -    my ($nodeInfo, $module, $context) = @_;
 +    my $optsAndSelectors = shift;
  
 -    my $depth = $nodeInfo->{depth};
 -    my $index = $nodeInfo->{idx};
 -    my $count = $nodeInfo->{count};
 -    my $build = $nodeInfo->{build};
 -    my $currentItem = $nodeInfo->{currentItem};
 -    my $currentBranch = $nodeInfo->{currentBranch};
 -    my $parentItem = $nodeInfo->{parentItem};
 -    my $parentBranch = $nodeInfo->{parentBranch};
 +    croak_internal("No options and selectors passed")
 +        unless $optsAndSelectors;
  
 -    my $buildStatus = $build ? 'built' : 'not built';
 -    my $statusInfo = $currentBranch ? "($buildStatus: $currentBranch)" : "($buildStatus)";
 +    my $version = "kdesrc-build " . scriptVersion();
 +    my $author = <<DONE;
 +$version was written (mostly) by:
 +  Michael Pyne <mpyne\@kde.org>
  
 -    my $connectorStack = $context->{stack};
 +Many people have contributed code, bugfixes, and documentation.
  
 +Please report bugs using the KDE Bugzilla, at https://bugs.kde.org/
 +DONE
  
 -    my $prefix = pop(@$connectorStack);
 +    my %optionHandlers = (
 +        'show-info' => sub { say "$version\nOS: ", ksb::OSSupport->new->vendorID(); },
 +        version     => sub { say $version },
 +        author      => sub { say $author  },
 +        help        => sub { _showHelpMessage() },
 +    );
  
 -    while($context->{depth} > $depth) {
 -        $prefix = pop(@$connectorStack);
 -        --($context->{depth});
 +    my $globalOpts = $optsAndSelectors->{options}->{global};
 +    foreach my $early_opt (keys %optionHandlers) {
 +        if (exists $globalOpts->{$early_opt}) {
 +            $optionHandlers{$early_opt}->();
 +            exit;
 +        }
      }
 +}
  
 -    push(@$connectorStack, $prefix);
 +# Method: handleQueryOptions
 +#
 +# Uses the user-requested options (as held in the build context) and handles
 +# any options that require the configuration file to be read (in particular
 +# --query and potentially other debug-flags options), before the backend is
 +# launched. Requires that selectors have been fully converted into modules.
 +#
 +# This function may exit entirely for some options!
 +#
 +# Phase:
 +#  initialization - Do not call <finish> from this function.
 +#
 +# Parameters:
 +#  None.
 +#
 +# Returns:
 +#  There is no return value. The function may not return at all, and exit instead.
 +sub handleQueryOptions
 +{
 +    my $self = assert_isa(shift, 'ksb::Application');
 +    my $ctx = $self->context();
  
 -    my $connector;
 +    my %optionHandlers = (
 +        query       => sub {
 +            my $queryMode = shift;
 +            my @modules = @{$self->{modules}};
 +
 +            # Default to ->getOption as query method.
 +            # $_[0] is short name for first param.
 +            my $query = sub { $_[0]->getOption($queryMode) };
 +            $query = sub { $_[0]->fullpath('source') } if $queryMode eq 'source-dir';
 +            $query = sub { $_[0]->fullpath('build') }  if $queryMode eq 'build-dir';
 +            $query = sub { $_[0]->installationPath() } if $queryMode eq 'install-dir';
 +            $query = sub { $_[0]->fullProjectPath() }  if $queryMode eq 'project-path';
 +            $query = sub { ($_[0]->scm()->_determinePreferredCheckoutSource())[0] // '' }
 +                if $queryMode eq 'branch';
 +
 +            if (@modules == 1) {
 +                # No leading module name, just the value
 +                say $query->($modules[0]);
 +            }
 +            else {
 +                for my $m (@modules) {
 +                    say "$m: ", $query->($m);
 +                }
 +            }
 +        },
 +    );
  
 -    if ($depth == 0) {
 -        $connector = $prefix . ' ── ';
 -        push(@$connectorStack, $prefix . (' ' x 4));
 -    }
 -    else {
 -        $connector = $prefix . ($index == $count ? '└── ': '├── ');
 -        push(@$connectorStack, $prefix . ($index == $count ? ' ' x 4: '│   '));
 +    foreach my $query_opt (keys %optionHandlers) {
 +        if (my $opt_value = $ctx->getOption($query_opt, 'module')) {
 +            $optionHandlers{$query_opt}->($opt_value);
 +            exit;
 +        }
      }
 -
 -    $context->{depth} = $depth + 1;
 -    $context->{report}($connector . $currentItem . ' ' . $statusInfo);
  }
  
 -# Generates the build context and module list based on the command line options
 -# and module selectors provided, resolves dependencies on those modules if needed,
 -# filters out ignored or skipped modules, and sets up the module factory.
 +# Method: _applyBuildContextPhasesFromCmdline
  #
 -# After this function is called all module set selectors will have been
 -# expanded, and we will have downloaded kde-projects metadata.
 +# Uses the user-requested options (as returned by
 +# readCommandLineOptionsAndSelectors) to update the build context and
 +# self-options as appropriate, including functions such as updating the
 +# run-mode. Options that might cause early exit are not handled, see
 +# _handleEarlyOptions for those.
  #
 -# Returns: a hash containing the following entries:
 +# Since the rc-file has not been read yet, this does not handle all possible
 +# cases where an early exit is required.
  #
 -#  - selectedModules: the selected modules to build
 -#  - dependencyInfo: reference to dependency info object as created by ksb::DependencyResolver
 -#  - build: whether or not to actually perform a build action
 +# Phase:
 +#  initialization - Do not call <finish> from this function.
  #
 -sub generateModuleList
 +# Parameters:
 +#  ctx - <BuildContext> to hold the global build state.
 +#  optsAndSelectors - As from readCommandLineOptionsAndSelectors
 +#
 +# Returns:
 +#  There is no return value.
 +sub _applyBuildContextPhasesFromCmdline
  {
 -    my $self = shift;
 -    my @argv = @_;
 +    my ($self, $ctx, $optsAndSelectors) = @_;
  
 -    # Note: Don't change the order around unless you're sure of what you're
 -    # doing.
 +    my $phases = $ctx->phases();
  
 -    my $ctx = $self->context();
 -    my $cmdlineOptions = { global => { }, };
 -    my $cmdlineGlobalOptions = $cmdlineOptions->{global};
 -    my $deferredOptions = { }; # 'options' blocks
 +    my %optionHandlers = (
 +        'no-src' => sub {
 +            $phases->filterOutPhase('update');
 +        },
 +        'no-install' => sub {
 +            $phases->filterOutPhase('install');
 +        },
 +        # run-tests is handled as a 'flag' and is only cmdline accessible as
 +        # --run-tests or --no-run-tests, both resulting in a value to run-tests hash
 +        'run-tests' => sub {
 +            ($_[0] // 1) ? $phases->addPhase      ('test')
 +                         : $phases->filterOutPhase('test');
 +        },
 +        'no-build' => sub {
 +            $phases->filterOutPhase('build');
 +        },
 +        install => sub {
 +            $phases->phases('install');
 +        },
 +        uninstall => sub {
 +            $phases->phases('uninstall');
 +        },
 +        # Mostly equivalent to the above
 +        'src-only' => sub {
 +            $phases->phases('update');
 +        },
 +        'build-only' => sub {
 +            $phases->phases('build');
 +        },
 +        resume => sub {
 +            $phases->filterOutPhase('update'); # Implied --no-src
 +        },
 +    );
  
 -    # Process --help, --install, etc. first.
 -    my @selectors;
 -    $self->_readCommandLineOptionsAndSelectors($cmdlineOptions, \@selectors,
 -        $ctx, @argv);
 +    while (my ($opt, $value) = each %{$optsAndSelectors->{options}->{global}}) {
 +        $optionHandlers{$opt}->($value) if exists $optionHandlers{$opt};
 +    }
 +}
  
 -    # Ensure some critical Perl modules are available so that the user isn't surprised
 -    # later with a Perl exception
 -    if(my @missingModuleDescriptions = _findMissingModules()) {
 -        say <<EOF;
 -kdesrc-build requires some minimal support to operate, including support
 -from the Perl runtime that kdesrc-build is built upon.
 +# This subroutine creates the ksb::BuildContext using the provided cmdline
 +# options/selectors and reads the config file and persistent options based on
 +# those cmdline options.
 +#
 +# After this function completes the build context and module resolver are ready
 +# for operations, but no module sets have been expanded and KDE project
 +# metadata has not been loaded. No changes are made to the passed-in
 +# options/selectors except to remove flags which do not apply to modules (like
 +# --run).
 +#
 +# See also: establishContext, which is probably what you actually want.
 +#
 +# Exceptions are possible (e.g. for malformed rc-files)
 +sub createBuildContextWithoutMetadata
 +{
 +    my ($self, $ctx, $optsAndSelectors) = @_;
  
 -Some mandatory Perl modules are missing, and kdesrc-build cannot operate
 -without them.  Please ensure these modules are installed and available to Perl:
 -EOF
 -        say "\t$_" foreach @missingModuleDescriptions;
 +    my $cmdlineOptions = $optsAndSelectors->{options};
 +    my $cmdlineGlobalOptions = $cmdlineOptions->{global};
  
 -        say "\nkdesrc-build can do this for you on many distros:";
 -        say "Run 'kdesrc-build --initial-setup'";
 +    # Setup module resolver
 +    my $moduleResolver
 +        = $self->{module_resolver}
 +        = ksb::ModuleResolver->new($ctx);
 +    $moduleResolver->setCmdlineOptions($cmdlineOptions);
 +    $moduleResolver->setIgnoredSelectors($cmdlineGlobalOptions->{'ignore-modules'});
  
 -        # TODO: Built-in mapping to popular distro package names??
 -        exit 1;
 +    # rc-file needs special handling.
 +    if (my $rcFile = ($cmdlineGlobalOptions->{'rc-file'} // '')) {
 +        $ctx->setRcFile($rcFile);
      }
  
-     # _readConfigurationOptions will add pending global opts to ctx while
-     # ensuring returned modules/sets have any such options stripped out. It
-     # will also add module-specific options to any returned modules/sets. This
-     # is done by adjusting the moduleResolver.
-     _readConfigurationOptions($ctx, $moduleResolver);
- 
-     $ctx->loadPersistentOptions();
- 
 -    # Convert list to hash for lookup
 -    my %ignoredSelectors =
 -        map { $_, 1 } @{$cmdlineGlobalOptions->{'ignore-modules'}};
 +    # Set aside debug-related and other short-circuit cmdline options
 +    # for kdesrc-build CLI driver to handle
 +    my @debugFlags = qw(dependency-tree list-build print-modules);
 +    $self->{debugFlags} = {
 +        map { ($_, 1) } # turns list of matches into list of key/value pairs for hash
 +            grep { defined $cmdlineGlobalOptions->{$_} }
 +                (@debugFlags)
 +    };
  
 -    my @startProgramAndArgs = @{$cmdlineGlobalOptions->{'start-program'}};
 +    # These options are only used for cmdline handling (and in fact
 +    # ksb::BuildContext will complain if we pass them) so delete them now.
      delete @{$cmdlineGlobalOptions}{qw/ignore-modules start-program/};
  
 -    # rc-file needs special handling.
 -    if (exists $cmdlineGlobalOptions->{'rc-file'} && $cmdlineGlobalOptions->{'rc-file'}) {
 -        $ctx->setRcFile($cmdlineGlobalOptions->{'rc-file'});
 -    }
 +    # Everything else in cmdlineOptions should be OK to apply directly as a
 +    # module or context option.
 +    $ctx->setOption(%{$cmdlineGlobalOptions});
+ 
 -    # disable async if only running a single phase.
 -    $cmdlineGlobalOptions->{async} = 0 if (scalar $ctx->phases()->phases() == 1);
++    # _readConfigurationOptions will add pending global opts to ctx while
++    # ensuring returned modules/sets have any such options stripped out. It
++    # will also add module-specific options to any returned modules/sets. This
++    # is done by adjusting the moduleResolver.
++    _readConfigurationOptions($ctx, $moduleResolver);
+ 
 -    my $fh = $ctx->loadRcFile();
+     $ctx->loadPersistentOptions();
 +}
 +
 +# Returns a list of selectors that should be added to the overall selector
 +# list, based on --rebuild-failures and --resume statements on the cmdline.
 +# Requires the build context to be setup with persistent options loaded.
 +sub getResumeSelectorsFromCmdline
 +{
 +    my ($self, $ctx, $optsAndSelectors) = @_;
 +
 +    my @selectors;
 +    my $cmdlineGlobalOptions = $optsAndSelectors->{options}->{global};
  
      if (exists $cmdlineGlobalOptions->{'resume'}) {
          my $moduleList = $ctx->getPersistentOption('global', 'resume-list');
@@@ -1317,10 -1225,7 +1318,11 @@@ sub _parseModuleSetOption
  sub _readConfigurationOptions
  {
      my $ctx = assert_isa(shift, 'ksb::BuildContext');
 -    my ($fh, $cmdlineGlobalOptions, $deferredOptionsRef) = @_;
 +    my $moduleResolver = assert_isa(shift, 'ksb::ModuleResolver');
 +
 +    my $fh = $ctx->loadRcFile();
++    my $cmdlineGlobalOptions = $moduleResolver->{cmdlineOptions}->{global};
 +    my $deferredOptionsRef = { };
      my @module_list;
      my $rcfile = $ctx->rcFile();
      my ($option, %readModules);
diff --cc modules/ksb/BuildSystem/CMake.pm
index f6cb42c,188fa2d..b5c424f
--- a/modules/ksb/BuildSystem/CMake.pm
+++ b/modules/ksb/BuildSystem/CMake.pm
@@@ -326,11 -359,27 +344,23 @@@ sub installInterna
  
  sub configureInternal
  {
 -    my $self = assert_isa(shift, 'ksb::BuildSystem::KDE4');
 +    my $self = assert_isa(shift, 'ksb::BuildSystem::CMake');
+     my $module = $self->module();
  
      # Use cmake to create the build directory (sh script return value
      # semantics).
-     return ($self->_safe_run_cmake() == 0);
 -    if ($self->_safe_run_cmake())
 -    {
 -        error ("\tUnable to configure r[$module] with CMake!");
 -        return 0;
 -    }
++    return 0 if ($self->_safe_run_cmake());
+ 
+     # handle the linking of compile_commands.json back to source directory if wanted
+     # allows stuff like clangd to function out of the box
+     if ($module->getOption('compile-commands-linking')) {
+         # symlink itself will keep existing files untouched!
+         my $builddir = $module->fullpath('build');
+         my $srcdir = $module->fullpath('source');
+         symlink("$builddir/compile_commands.json", "$srcdir/compile_commands.json") if -e "$builddir/compile_commands.json";
+     }
+ 
+     return 1;
  }
  
  # Return value style: boolean
diff --cc t/smoke/issue-64-cmdline-opt-override.t
index 0000000,35450b6..4dbf193
mode 000000,100644..100644
--- a/t/smoke/issue-64-cmdline-opt-override.t
+++ b/t/smoke/issue-64-cmdline-opt-override.t
@@@ -1,0 -1,77 +1,76 @@@
 -use 5.014;
 -use strict;
++use v5.22;
+ use warnings;
+ 
+ # Global options in the rc-file can be overridden on the command line just by
+ # using their option name in a cmdline argument (as long as the argument isn't
+ # already allocated, that is).
+ #
+ # This ensures that global options overridden in this fashion are applied
+ # before the rc-file is read.
+ #
+ # See issue #64
+ 
+ use Test::More;
+ 
+ use ksb::Application;
+ use ksb::Module;
+ 
+ # The issue used num-cores as an example, but should work just as well
+ # with make-options
+ my @args = qw(--pretend --rc-file t/data/sample-rc/kdesrc-buildrc);
+ {
 -    my $app = ksb::Application->new(@args);
 -    my @moduleList = @{$app->{modules}};
++    my $app = ksb::Application::newFromCmdline(@args)->setHeadless;
++    my @moduleList = $app->modules();
+ 
+     is ($app->context()->getOption('num-cores'), 8, 'No cmdline option leaves num-cores value alone');
+ 
+     is (scalar @moduleList, 4, 'Right number of modules');
+     is ($moduleList[0]->name(), 'setmod1', 'mod list[0] == setmod1');
+     is ($moduleList[0]->getOption('make-options'), '-j4', 'make-options base value proper pre-override');
+ 
+     is ($moduleList[3]->name(), 'module2', 'mod list[3] == module2');
+     is ($moduleList[3]->getOption('make-options'), '-j 8', 'module-override make-options proper pre-override');
+ }
+ 
+ # We can't seem to assign -j3 as Getopt::Long will try to understand the option
+ # and fail
+ push @args, '--make-options', 'j3';
+ 
+ {
 -    my $app = ksb::Application->new(@args);
 -    my @moduleList = @{$app->{modules}};
++    my $app = ksb::Application::newFromCmdline(@args)->setHeadless;
++    my @moduleList = $app->modules();
+ 
+     is ($app->context()->getOption('num-cores'), 8, 'No cmdline option leaves num-cores value alone');
+ 
+     is (scalar @moduleList, 4, 'Right number of modules');
+     is ($moduleList[0]->name(), 'setmod1', 'mod list[0] == setmod1');
+     is ($moduleList[0]->getOption('make-options'), 'j3', 'make-options base value proper post-override');
+ 
+     # Policy discussion: Should command line options override *all* instances
+     # of an option in kdesrc-buildrc? Historically the answer has deliberately
+     # been yes, so that's the behavior we enforce.
+     is ($moduleList[3]->name(), 'module2', 'mod list[3] == module2');
+     is ($moduleList[3]->getOption('make-options'), 'j3', 'module-override make-options proper post-override');
+ }
+ 
+ # Remove last two args and add another test of indirect option value setting
+ 
+ pop @args;
+ pop @args;
+ push @args, '--num-cores=5'; # 4 is default, 8 is in rc-file, use something different
+ 
+ {
 -    my $app = ksb::Application->new(@args);
 -    my @moduleList = @{$app->{modules}};
++    my $app = ksb::Application::newFromCmdline(@args)->setHeadless;
++    my @moduleList = $app->modules();
+ 
+     is ($app->context()->getOption('num-cores'), 5, 'Updated cmdline option changes global value');
+ 
+     is (scalar @moduleList, 4, 'Right number of modules');
+     is ($moduleList[0]->name(), 'setmod1', 'mod list[0] == setmod1');
+     is ($moduleList[0]->getOption('make-options'), '-j4', 'make-options base value proper post-override (indirect value)');
+ 
+     is ($moduleList[3]->name(), 'module2', 'mod list[3] == module2');
+     is ($moduleList[3]->getOption('make-options'), '-j 5', 'module-override make-options proper post-override (indirect value)');
+ }
+ 
+ done_testing();
diff --cc vim/syntax/kdesrc-buildrc.vim
index 3e6ef72,7660ed7..d789047
--- a/vim/syntax/kdesrc-buildrc.vim
+++ b/vim/syntax/kdesrc-buildrc.vim
@@@ -67,10 -68,10 +68,10 @@@ syn keyword ksbrcBoolOption contained s
              \ build-system-only build-when-unchanged ignore-kde-structure
              \ include-dependencies install-after-build manual-build manual-update
              \ no-src reconfigure recreate-configure refresh-build run-tests
-             \ use-clean-install
+             \ use-clean-install compile-commands-export compile-commands-linking
  
  syn keyword ksbrcGlobalBoolOption contained skipwhite nextgroup=ksbrcBoolValue
 -            \ async colorful-output disable-agent-check disable-snapshots pretend
 +            \ colorful-output disable-agent-check disable-snapshots pretend
              \ purge-old-logs stop-on-failure use-idle-io-priority install-session-driver
              \ install-environment-driver
  



More information about the kde-doc-english mailing list