[kde-doc-english] [kdesrc-build/dependency-format-v2] /: Add new option 'include-dependencies'.

Michael Pyne mpyne at kde.org
Sun Feb 22 03:13:45 UTC 2015


Git commit b452401f50d3c740e8529986bf19e074920be0c6 by Michael Pyne.
Committed on 22/02/2015 at 03:07.
Pushed by mpyne into branch 'dependency-format-v2'.

Add new option 'include-dependencies'.

Currently it (probably) doesn't support pulling in options for these
modules from their host module-sets (although using 'options' sections
might actually work). I think it ignores the 'ignore-modules' option as
well.

Other than that, it should do pretty much what it says on the tin,
although I had to implement a few other bug fixes as well to get it to
that point.

I want to say that there was an open bug for this but I can't seem to
find it now.

M  +20   -0    doc/index.docbook
M  +2    -1    kdesrc-buildrc.xml
M  +4    -0    kf5-workspace-build-include
M  +40   -4    modules/ksb/Application.pm
M  +58   -20   modules/ksb/DependencyResolver.pm
M  +3    -3    vim/syntax/kdesrc-buildrc.vim

http://commits.kde.org/kdesrc-build/b452401f50d3c740e8529986bf19e074920be0c6

diff --git a/doc/index.docbook b/doc/index.docbook
index 03ac845..0103c5d 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -2067,6 +2067,26 @@ is compared).</para>
 </entry>
 </row>
 
+<row id="conf-include-dependencies">
+<entry>include-dependencies</entry>
+<entry>Module setting overrides global</entry>
+<entry>
+<para>This option, when set to <userinput>true</userinput> requests that
+&kdesrc-build; also include known dependencies of this module in its build,
+without requiring you to mention those dependencies (even indirectly).</para>
+
+<note><para>This option only works for <link
+linkend="kde-projects-module-sets"><literal>kde-project</literal>-based
+modules</link>, and requires that the metadata maintained by the &kde;
+developers is accurate for your selected <link
+linkend="conf-branch-group">branch-group</link>.</para></note>
+
+<para>This option is disabled by default, to avoid inadvertently selecting a
+bunch of modules that were not desired. It was added with &kdesrc-build;
+1.16 in 2015.</para>
+</entry>
+</row>
+
 <row id="conf-install-after-build">
 <entry>install-after-build</entry>
 <entry>Module setting overrides global</entry>
diff --git a/kdesrc-buildrc.xml b/kdesrc-buildrc.xml
index 2abf2c9..327d7c6 100644
--- a/kdesrc-buildrc.xml
+++ b/kdesrc-buildrc.xml
@@ -4,7 +4,7 @@
      it can go to $KDEHOME/share/apps/katepart/syntax
  -->
 <language name = "kdesrc-buildrc"
-       version = "0.6.2"
+       version = "0.6.3"
    kateversion = "3.5"
        section = "Configuration"
     extensions = ".kdesrc-buildrc;kdesrc-buildrc;.kdesvn-buildrc;kdesvn-buildrc"
@@ -29,6 +29,7 @@
     <list name="moduleSetOptions">
       <item>use-modules</item>
       <item>ignore-modules</item>
+      <item>include-dependencies</item>
     </list>
 
     <!-- These options should only have a boolean value passed to them. -->
diff --git a/kf5-workspace-build-include b/kf5-workspace-build-include
index 5f9903d..4e71d6b 100644
--- a/kf5-workspace-build-include
+++ b/kf5-workspace-build-include
@@ -21,6 +21,10 @@ module-set kf5-workspace-modules
 
     use-modules workspace plasmate kde-gtk-config libkscreen
 
+    # kdesrc-build will build dependencies (that it knows about) even if you forget
+    # to list them all.
+    include-dependencies true
+
     # Remove if you're somehow using Windows
     ignore-modules kwindowsaddons
 end module-set
diff --git a/modules/ksb/Application.pm b/modules/ksb/Application.pm
index fa47a7e..90cf8e9 100644
--- a/modules/ksb/Application.pm
+++ b/modules/ksb/Application.pm
@@ -58,6 +58,8 @@ sub new
         metadata_module => undef,
         run_mode        => 'build',
         modules         => undef,
+        module_factory  => undef, # ref to sub that makes a new Module.
+                                  # See generateModuleList
         _base_pid       => $$, # See finish()
     }, $class;
 
@@ -512,7 +514,7 @@ sub _resolveSelectorsIntoModules
 }
 
 # Generates the build context and module list based on the command line options
-# and module selectors provided.
+# and module selectors provided, and sets up the module factory.
 #
 # After this function is called all module set selectors will have been
 # expanded, and we will know if we need to download kde-projects metadata or
@@ -614,6 +616,9 @@ sub generateModuleList
         delete @{$module->{options}}{@globalCmdlineArgs};
     };
 
+    # Called here since it depends on the closure above
+    $self->_defineNewModuleFactory($newModuleSub);
+
     if ($commandLineModules) {
         # select our modules and module-sets, and expand them out
         @modules = $self->_resolveSelectorsIntoModules(
@@ -698,8 +703,9 @@ sub _downloadKDEProjectMetadata
 # Returns a list of Modules in the proper build order according to the
 # kde-build-metadata dependency information.
 #
-# The kde-build-metadata repository must have already been updated. The Modules
-# to reorder must be passed as arguments.
+# The kde-build-metadata repository must have already been updated, and the
+# module factory must be setup. The Modules to reorder must be passed as
+# arguments.
 sub _resolveModuleDependencies
 {
     my $self = shift;
@@ -708,7 +714,7 @@ sub _resolveModuleDependencies
     my @modules = @_;
 
     @modules = eval {
-        my $dependencyResolver = ksb::DependencyResolver->new();
+        my $dependencyResolver = ksb::DependencyResolver->new($self->{module_factory});
         my $branchGroup = $ctx->effectiveBranchGroup();
 
         for my $file ('dependency-data-common', "dependency-data-$branchGroup")
@@ -2184,6 +2190,36 @@ sub _expandModuleSets
     return @moduleResults;
 }
 
+# This defines the factory function needed for lower-level code to properly be
+# able to create ksb::Module objects from just the module name, while still
+# having the options be properly set and having the module properly tied into a
+# context.
+sub _defineNewModuleFactory
+{
+    my ($self, $newModuleSub) = @_;
+    my $ctx = $self->context();
+    my $projSet = ksb::ModuleSet::KDEProjects->new($ctx, '<kde-project auto-dep>');
+
+    $self->{module_factory} = sub {
+        my $name = shift;
+        $projSet->setModulesToFind($name);
+        my @results = $projSet->convertToModules($ctx);
+
+        # Thought experiment: a module depends on phonon/phonon, which gets duly
+        # shortened to 'phonon'. Our kde-project code expands that by default to
+        # 'phonon/*', which returns {phonon,phonon-vlc,phonon-gstreamer}, etc.
+        # We need to make sure to return only matching modules.
+        my @mods = grep { $_->name() eq $name } (@results);
+        if (@mods > 1) {
+            croak_runtime ("Too many modules match $name; results were " .
+                join(', ', @mods)."\nCandidates @results");
+        }
+
+        $newModuleSub->($mods[0]);
+        return $mods[0];
+    };
+}
+
 # This function converts any 'l10n' references on the command line to return a l10n
 # module with the proper build system, scm type, etc.
 #
diff --git a/modules/ksb/DependencyResolver.pm b/modules/ksb/DependencyResolver.pm
index 77c1e6e..8d39bda 100644
--- a/modules/ksb/DependencyResolver.pm
+++ b/modules/ksb/DependencyResolver.pm
@@ -18,16 +18,23 @@ use List::Util qw(first);
 
 # Constructor: new
 #
-# Constructs a new <DependencyResolver>. No parameters are taken.
+# Constructs a new <DependencyResolver>.
+#
+# Parameters:
+#
+#   moduleFactoryRef - Reference to a sub that creates ksb::Modules from
+#     kde-project module names. Used for ksb::Modules for which the user
+#     requested recursive dependency inclusion.
 #
 # Synposis:
 #
-# > my $resolver = new DependencyResolver;
+# > my $resolver = new DependencyResolver($modNewRef);
 # > $resolver->readDependencyData(open my $fh, '<', 'file.txt');
 # > $resolver->resolveDependencies(@modules);
 sub new
 {
     my $class = shift;
+    my $moduleFactoryRef = shift;
 
     my $self = {
         # hash table mapping short module names (m) to a hashref key by branch
@@ -41,6 +48,11 @@ sub new
         # hash table mapping a wildcarded module name with no branch to a
         # listref of module:branch dependencies.
         catchAllDependencies => { },
+
+        # reference to a sub that will properly create a ksb::Module from a
+        # given kde-project module name. Used to support automatically adding
+        # dependencies to a build.
+        moduleFactoryRef => $moduleFactoryRef,
     };
 
     return bless $self, $class;
@@ -298,29 +310,31 @@ sub _getBranchOf
 #   module build list, module name to <ksb::Module> mapping, and auxiliary data
 #   to see if a module has already been visited.
 #  module - The <ksb::Module> to properly order in the build list.
+#  level - The level of recursion of this call.
+#  dependent - Identical to the same param as _visitDependencyItemAndDependencies
 #
 # Returns:
 #  Nothing. The proper build order can be read out from the optionsRef passed
 #  in.
 sub _visitModuleAndDependencies
 {
-    my ($optionsRef, $module, $level) = @_;
+    my ($optionsRef, $module, $level, $dependentName) = @_;
     assert_isa($module, 'ksb::Module');
 
     if ($module->scmType() eq 'proj') {
         my $item = _shortenModuleName($module->fullProjectPath());
         my $branch = _getBranchOf($module) // '*';
-        _visitDependencyItemAndDependencies($optionsRef, "$item:$branch", $level);
-    }
 
-    # It's possible for _visitDependencyItemAndDependencies to add *this*
-    # module without it being a cycle, so make sure we don't duplicate.
-    if (! grep { $_->name() eq $module->name() } @{$optionsRef->{properBuildOrder}}) {
-        $module->setOption('#dependency-level', $level);
-        push @{$optionsRef->{properBuildOrder}}, $module;
-        --($optionsRef->{modulesNeeded});
+        $dependentName //= $item if $module->getOption('include-dependencies');
+        _visitDependencyItemAndDependencies($optionsRef, "$item:$branch", $level, $dependentName);
+
+        $optionsRef->{visitedItems}->{$item} = 3; # Mark as also in build list
     }
 
+    $module->setOption('#dependency-level', $level);
+    push @{$optionsRef->{properBuildOrder}}, $module;
+    --($optionsRef->{modulesNeeded});
+
     return;
 }
 
@@ -345,18 +359,26 @@ sub _visitModuleAndDependencies
 #   ':', and the specific branch name for the dependency if needed. The branch
 #   name is '*' if the branch doesn't matter (or can be determined only by the
 #   branch-group in use). E.g. 'baloo:*' or 'akonadi:master'.
+#  level - Level of recursion of the current call.
+#  dependent - *if set*, is the name of the module that requires that all of its
+#   dependencies be added to the build list (properly ordered) even if not
+#   specifically selected in the configuration file or command line. If not set,
+#   recursive dependencies are not pulled into the build even if they are not
+#   in the build list.
 #
 # Returns:
 #  Nothing. The proper build order can be read out from the optionsRef passed
-#  in.
+#  in. Note that the generated build list might be longer than the build list that
+#  was input, in the case that recursive dependency inclusion was requested.
 sub _visitDependencyItemAndDependencies
 {
-    my ($optionsRef, $dependencyItem, $level) = @_;
+    my ($optionsRef, $dependencyItem, $level, $dependentName) = @_;
 
     my $visitedItemsRef     = $optionsRef->{visitedItems};
     my $properBuildOrderRef = $optionsRef->{properBuildOrder};
     my $dependenciesOfRef   = $optionsRef->{dependenciesOf};
     my $modulesFromNameRef  = $optionsRef->{modulesFromName};
+    my $moduleFactoryRef    = $optionsRef->{moduleFactoryRef};
     $level //= 0;
 
     my ($item, $branch) = split(':', $dependencyItem, 2);
@@ -366,14 +388,20 @@ sub _visitDependencyItemAndDependencies
     $visitedItemsRef->{$item} //= 0;
 
     # This module may have already been added to build.
-    return if $visitedItemsRef->{$item} == 1;
+    # 0 == Not visited
+    # 1 == Currently visiting. Running into a module in visit state 1 indicates a cycle.
+    # 2 == Visited, but not in build (this may happen for common dependencies with siblings, or for
+    #      modules that are not in our build list but are part of dependency chain for other modules
+    #      that *are* in build list).
+    # 3 == Visited, placed in build queue.
+    return if $visitedItemsRef->{$item} >= 2;
 
     # But if the value is 2 that means we've detected a cycle.
-    if ($visitedItemsRef->{$item} > 1) {
+    if ($visitedItemsRef->{$item} == 1) {
         croak_internal("Somehow there is a dependency cycle involving $item! :(");
     }
 
-    $visitedItemsRef->{$item} = 2; # Mark as currently-visiting for cycle detection.
+    $visitedItemsRef->{$item} = 1; # Mark as currently-visiting for cycle detection.
 
     _makeCatchAllRules($optionsRef, $item);
 
@@ -385,28 +413,36 @@ sub _visitDependencyItemAndDependencies
 
         # This keeps us from doing a deep recursive search for dependencies
         # on an item we've already asked about.
-        next if (($visitedItemsRef->{$subItemName} // 0) == 1);
+        next if (($visitedItemsRef->{$subItemName} // 0) >= 2);
 
         debug ("\tdep-resolv: $item:$branch depends on $subItem");
 
         my $subModule = $modulesFromNameRef->{$subItemName};
-        if (!$subModule) {
+        if (!$subModule && !$dependentName) {
             whisper (" y[b[*] $dependencyItem depends on $subItem, but no module builds $subItem for this run.");
             _visitDependencyItemAndDependencies($optionsRef, $subItem, $level + 1);
         }
         else {
+            # Add in the dependent module if requested.
+            if (!$subModule) {
+                $subModule = $moduleFactoryRef->($subItemName);
+                $modulesFromNameRef->{$subModule->name()} = $subModule;
+                ++($optionsRef->{modulesNeeded});
+            }
+
             if ($subItemBranch ne '*' && (_getBranchOf($subModule) // '') ne $subItemBranch) {
                 my $wrongBranch = _getBranchOf($subModule) // '?';
                 error (" r[b[*] $item needs $subItem, not $subItemName:$wrongBranch");
             }
 
-            _visitModuleAndDependencies($optionsRef, $subModule, $level + 1);
+            _visitModuleAndDependencies($optionsRef, $subModule, $level + 1, $dependentName);
         }
 
         last if $optionsRef->{modulesNeeded} == 0;
     }
 
-    $visitedItemsRef->{$item} = 1; # Mark as done visiting.
+    # Mark as done visiting.
+    $visitedItemsRef->{$item} = 2;
     return;
 }
 
@@ -453,6 +489,8 @@ sub resolveDependencies
                 @modules
         },
 
+        moduleFactoryRef => $self->{moduleFactoryRef},
+
         # Help _visitModuleAndDependencies to optimize
         modulesNeeded => scalar @modules,
     };
diff --git a/vim/syntax/kdesrc-buildrc.vim b/vim/syntax/kdesrc-buildrc.vim
index e5d03fd..8b60c5c 100644
--- a/vim/syntax/kdesrc-buildrc.vim
+++ b/vim/syntax/kdesrc-buildrc.vim
@@ -1,7 +1,7 @@
 " Vim syntax file
 " Language: kdesrc-build configuration file
 " Maintainer: Michael Pyne <mpyne at kde.org>
-" Latest Revision: 8 February 2015
+" Latest Revision: 21 February 2015
 
 " Copyright (c) 2014,2015 Michael Pyne <mpyne at kde.org>
 " Redistribution and use in source and binary forms, with or without
@@ -54,12 +54,12 @@ syn keyword ksbrcErrorGlobalOption contained skipwhite nextgroup=ksbrcStringValu
             \ kde-languages niceness debug-level persistent-data-file set-env
 
 syn keyword ksbrcModuleSetOption contained skipwhite nextgroup=ksbrcStringValue
-            \ use-modules ignore-modules
+            \ use-modules ignore-modules include-dependencies
 
 " MUST BE CONSISTENT WITH ABOVE. Used when a module-set option is used in the
 " wrong spot to highlight the error.
 syn keyword ksbrcErrorModuleSetOption contained skipwhite nextgroup=ksbrcStringValue
-            \ use-modules ignore-modules
+            \ use-modules ignore-modules include-dependencies
 
 syn keyword ksbrcBoolOption contained skipwhite nextgroup=ksbrcBoolValue
             \ build-system-only build-when-unchanged ignore-kde-structure


More information about the kde-doc-english mailing list