diff --git a/Internals.txt b/Internals.txt new file mode 100644 index 0000000..0c7eab3 --- /dev/null +++ b/Internals.txt @@ -0,0 +1,81 @@ +Title: Module list construction + +An overview of the steps performed in constructing the module list: + +There are two parallel flows performed for module list construction + +1. Configuration file module list processing. The configuration file supports +modules of various types along with module-sets. Modules of the kde-project +type (available *only* from a module-set) can be converted later into 0, 1, or +more git modules. Modules are formed into the list in the order given in the +configuration file, but any modules implictly pulled in from the kde-project +modules will be sorted appropriately by kde-build-metadata. + +2. Modules can be directly specified on the command line. kde-projects modules +can be forced by preceding the module name with a '+'. + +After processing command line module names, any modules that match a module +(or module-set) given from the configuration file will have the configuration +file version of that module spliced into the list to replace the command line +one. + +So a graphical overview of configuration file modules + +> svn, git, setA/git, setA/git, setA/git, setB/proj + +which is proj-expanded to form (for instance) + +> svn, git, setA/git, setA/git, setA/git, setB/git, setB/git + +and is then filtered (respecting --resume-{from,after}) + +> setA/git, setA/git, setA/git, setB/git, setB/git + +(and even this leaves out some details, e.g. l10n). + +Command-line modules: + +kdesrc-build also constructs a list of command-line-passed modules. Since the +module names are read before the configuration file is even named (let alone +read) kdesrc-build has to hold onto the list until much later in +initialization before it can really figure out what's going on with the +command line. So the sequence looks more like: + +> nameA/??, nameB/??, +nameC/??, nameD/?? + +Then + names are forced to be proj-type + +> nameA/??, nameB/??, nameC/proj, nameD/?? + +From here we "splice" in configuration file modules that have matching names +to modules from the command line. + +> nameA/??, nameB/git, nameC/proj, nameD/?? + +Following this we run a filter pass to remove whole module-sets that we don't +care about (as the applyModuleFilters function cares only about +$module->name(). In this example nameA happened to match a module-set name +only. + +> nameB/git, nameC/proj, nameD/?? + +Finally we match and expand potential module-sets + +> nameB/git, nameC/proj, nameE/proj, nameF/proj + +Not only does this expansion try to splice in modules under a named +module-set, but it forces each module that doesn't already have a type into +having a 'proj' type but with a special "guessed name" annotation, which is +used later for proj-expansion. + +At this point we should be at the same point as if there were no command-line +modules, just before we expand kde-projects modules (yes, this means that the +--resume-* flags are checked twice for this case). At this point there is a +separate pass to ensure that all modules respect the --no-{src,build,etc.} +options if they had been read from the command line, but that could probably +be done at any time and still work just fine. + +One other nuance is that if _nameD/??_ above had *not* actually been part of a +module-set and was also not the name of an existing kde-project module, then +trying to proj-expand it would have resulted in an exception being thrown +(this is where the check for unknown modules occurs). diff --git a/kdesrc-build b/kdesrc-build index ea3e9f6..7f9818b 100755 --- a/kdesrc-build +++ b/kdesrc-build @@ -784,10 +784,37 @@ EOF return @moduleList; } +# Function: expandXMLModules +# # Goes through the provided modules that have the 'proj' type (i.e. XML # projects.kde.org database) and expands the proj-types into their equivalent # git modules, and returns the fully expanded list. Non-proj modules are # included in the sequence they were originally. +# +# *Note*: This function will trigger network download of the kde-projects +# database if any relevant modules are identified. In addition, a build-support +# module will be included in this case, which requires special care. +# +# *Note*: Any modules that are part of a module-set requiring a specific +# branch, that don't have that branch, are also elided with only a debug +# message. This allows for building older branches of KDE even when newer +# modules are eventually put into the database. +# +# Parameters: +# ctx - The in use. +# @modules - The list of to perform proj-expansion on. +# +# Returns: +# @modules - List of expanded . *Note*: If the build-support +# repository was included it will be the first , with an SCM type of +# . Many other support functions will +# require this metadata be updated first. +# +# Throws: +# Runtime - if the kde-projects database was required but couldn't be +# downloaded or read. +# Runtime - if the git-desired-protocol is unsupported. +# Runtime - if an "assumed" kde-projects module was not actually one. sub expandXMLModules { my $ctx = assert_isa(shift, 'ksb::BuildContext'); @@ -905,20 +932,32 @@ sub expandXMLModules return @results; } -# This subroutine takes a reference to the current module list (specifically a -# list of ksb::Module objects), and takes a reference to the list of ksb::Module objects -# read in from the config file. +# Function: expandModuleSets # -# For each module in the first list, it is checked to see if options have been -# read in for it, and if so it is left alone. +# Replaces in an input list from the command line that name +# module-sets listed in the configuration file, and returns the new list. # -# If the module does not have any options for it, it is assumed that the user -# might mean a named module set (i.e. the module is the name of a module-set), -# and /if/ any of the Modules in the second list are recorded as having come -# from a module set matching the name of the current module, it is used -# instead. +# A is assumed to name a module-set if all of the following are true. +# * No options were read in for it. +# * The module isn't already forced to be a kde-project module (as can happen +# on the command line). +# * from the rcFileModules were included in a module-set of the same +# name. # -# The processed module list is the return value. +# Any that meets these conditions is replaced by all of the matching +# module-set in the return list. +# +# Any that doesn't match a known rcFile module *or* module-set is +# assumed to be a kde-project module and altered appropriately. +# +# Parameters: +# $@modules - listref of to be expanded. +# $@rcFileModules - listref of that list modules read in from the +# configuration file. +# +# Returns: +# @modules - List of with any module-sets expanded into . +# No kde-project module expansion occurs. sub expandModuleSets { my ($buildModuleList, $knownModules) = @_; @@ -960,10 +999,26 @@ sub expandModuleSets return map { &$filter } (@$buildModuleList); } -# This subroutine reads in the settings from the user's configuration -# file. The filehandle to read from should be passed in as the first -# parameter. The filehandle should be something that the <> operator works -# on, usually some subclass of IO::Handle. +# Function: read_options +# +# Reads in the settings from the configuration, passed in as an open +# filehandle. +# +# Phase: +# initialization - Do not call from this function. +# +# Parameters: +# ctx - The to update based on the configuration read. +# filehandle - The I/O object to read from. Must handle _eof_ and _readline_ +# methods (e.g. subclass). +# +# Returns: +# @module - List of defined in the configuration file. Note that +# although any module-sets found will have been expanded out, no kde-projects +# modules will have been further expanded out. +# +# Throws: +# - Config exceptions. sub read_options { my $ctx = assert_isa(shift, 'ksb::BuildContext'); @@ -2394,18 +2449,24 @@ sub handle_uninstall return $result; } -# This subroutine is used in order to apply any module-specific filtering that -# is necessary after reading command line and rc-file options. (This is as -# opposed to phase filters, which leave each module as-is but change the phases -# they operate part of, this function could remove a module entirely from the -# build). +# Function: applyModuleFilters +# +# Applies any module-specific filtering that is necessary after reading command +# line and rc-file options. (This is as opposed to phase filters, which leave +# each module as-is but change the phases they operate as part of, this +# function could remove a module entirely from the build). # -# Famously used for --resume-from and --resume-after, but more could be added -# in theory. +# Used for --resume-from and --resume-after, but more could be added in theory. +# This subroutine supports --resume-* for both modules and module-sets. # -# Requires a list of "ksb::Module" type objects, and returns the list with filters -# applied. Right now the return list will be a subset of the given list, but -# it's best not to rely on that long-term. +# Parameters: +# ctx - in use. +# @modules - List of to apply filters on. +# +# Returns: +# list of with any inclusion/exclusion filters applied. Do not +# assume this list will be a strict subset of the input list, however the +# order will not change amongst the input modules. sub applyModuleFilters { my $ctx = assert_isa(shift, 'ksb::BuildContext'); diff --git a/modules/ksb/KDEXMLReader.pm b/modules/ksb/KDEXMLReader.pm index e46b44d..4546900 100644 --- a/modules/ksb/KDEXMLReader.pm +++ b/modules/ksb/KDEXMLReader.pm @@ -1,8 +1,14 @@ package ksb::KDEXMLReader; +# Class: KDEXMLReader +# # kde_projects.xml module-handling code. # The core of this was graciously contributed by Allen Winter, and then # touched-up and kdesrc-build'ed by myself -mpyne. +# +# In C++ terms this would be a singleton-class (as it uses package variables +# for everything due to XML::Parser limitations). So it is neither re-entrant +# nor thread-safe. use strict; use warnings; @@ -12,6 +18,15 @@ our $VERSION = '0.10'; use XML::Parser; +# Method: new +# +# Constructs a new KDEXMLReader. This doesn't contradict any part of the class +# documentation which claims this class is a singleton however. This should be +# called as a method (e.g. KDEXMLReader->new(...)). +# +# Parameters: +# $inputHandle - Ref to filehandle to read from. Must implement _readline_ and +# _eof_. sub new { my $class = shift;