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
