You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
8.3 KiB
231 lines
8.3 KiB
package ksb::ModuleSet::KDEProjects; |
|
|
|
# Class: ModuleSet::KDEProjects |
|
# |
|
# This represents a collective grouping of modules that share common options, |
|
# and are obtained via the kde-projects database at |
|
# https://projects.kde.org/kde_projects.xml |
|
# |
|
# See also the parent class ModuleSet, from which most functionality is derived. |
|
# |
|
# The only changes here are to allow for expanding out module specifications |
|
# (except for ignored modules), by using KDEXMLReader. |
|
# |
|
# See also: ModuleSet |
|
|
|
use strict; |
|
use warnings; |
|
use v5.10; |
|
no if $] >= 5.018, 'warnings', 'experimental::smartmatch'; |
|
|
|
our $VERSION = '0.10'; |
|
our @ISA = qw(ksb::ModuleSet); |
|
|
|
use ksb::Module; |
|
use ksb::Debug; |
|
use ksb::KDEXMLReader; |
|
use ksb::BuildContext 0.20; |
|
use ksb::Util; |
|
|
|
# A 'new' subroutine is not needed, ksb::ModuleSet's should do the right thing |
|
|
|
# Simple utility subroutine. See List::Util's perldoc |
|
sub none_true |
|
{ |
|
($_ && return 0) for @_; |
|
return 1; |
|
} |
|
|
|
# Function: getMetadataModule |
|
# |
|
# A 'static' method that returns a <Module> that should be included first in |
|
# the build context's module list. It will be configured to download required |
|
# updates to the build-metadata required for kde-projects module support. |
|
# It should only be included exactly once in the build context, if there are |
|
# one or more ksb::ModuleSet::KDEProjects present in the module list. |
|
# |
|
# Parameters: |
|
# ctx - the <ksb::BuildContext> for this script execution. |
|
# |
|
# Returns: The <Module> to added to the beginning of the update. |
|
sub getMetadataModule |
|
{ |
|
my $ctx = assert_isa(shift, 'ksb::BuildContext'); |
|
|
|
my $metadataModule = ksb::Module->new($ctx, 'kde-build-metadata'); |
|
|
|
# Hardcode the results instead of expanding out the project info |
|
$metadataModule->setOption('repository', 'kde:kde-build-metadata'); |
|
$metadataModule->setOption('#xml-full-path', 'kde-build-metadata'); |
|
$metadataModule->setOption('#branch:stable', 'master'); |
|
$metadataModule->setScmType('metadata'); |
|
$metadataModule->setOption('disable-snapshots', 1); |
|
$metadataModule->setOption('branch', 'master'); |
|
|
|
my $moduleSet = ksb::ModuleSet::KDEProjects->new($ctx, '<kde-projects metadata>'); |
|
$metadataModule->setModuleSet($moduleSet); |
|
|
|
# Ensure we only ever try to update source, not build. |
|
$metadataModule->phases()->phases('update'); |
|
return $metadataModule; |
|
} |
|
|
|
# Function: _expandModuleCandidates |
|
# |
|
# A class method which goes through the modules in our search list (assumed to |
|
# be found in the kde-projects XML database) and expands them into their |
|
# equivalent git modules, and returns the fully expanded list. Non kde-projects |
|
# modules cause an error, as do modules that do not exist at all within the |
|
# database. |
|
# |
|
# *Note*: Before calling this function, the kde-projects database itself must |
|
# have been downloaded first. Additionally a <Module> handling build support |
|
# metadata must be included at the beginning of the module list, see |
|
# getMetadataModule() for details. |
|
# |
|
# *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 <BuildContext> in use. |
|
# moduleSearchItem - The search description to expand in ksb::Modules. See |
|
# _projectPathMatchesWildcardSearch for a description of the syntax. |
|
# |
|
# Returns: |
|
# @modules - List of expanded git <Modules>. |
|
# |
|
# 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 _expandModuleCandidates |
|
{ |
|
my $self = assert_isa(shift, 'ksb::ModuleSet::KDEProjects'); |
|
my $ctx = assert_isa(shift, 'ksb::BuildContext'); |
|
my $moduleSearchItem = shift; |
|
|
|
my $databaseFile = $ctx->getKDEProjectMetadataFilehandle() or |
|
croak_runtime("kde-projects repository information could not be downloaded: $!"); |
|
my $srcdir = $ctx->getSourceDir(); |
|
|
|
my $protocol = $ctx->getOption('git-desired-protocol') || 'git'; |
|
if (!list_has(['git', 'http'], $protocol)) { |
|
error (" b[y[*] Invalid b[git-desired-protocol] $protocol"); |
|
error (" b[y[*] Try setting this option to 'git' if you're not using a proxy"); |
|
croak_runtime ("Invalid git-desired-protocol: $protocol"); |
|
} |
|
|
|
my $xmlReader = ksb::KDEXMLReader->new($databaseFile); |
|
my @allXmlResults = $xmlReader->getModulesForProject($moduleSearchItem, $protocol); |
|
|
|
croak_runtime ("Unknown KDE project: $moduleSearchItem") unless @allXmlResults; |
|
|
|
# It's possible to match modules which are marked as inactive on |
|
# projects.kde.org, elide those. |
|
my @xmlResults = grep { $_->{'active'} ne 'false' } (@allXmlResults); |
|
|
|
# Bug 307694 |
|
my $moduleSetBranch = $self->{'options'}->{'branch'} // ''; |
|
if ($moduleSetBranch && !exists $self->{'options'}->{'tag'}) { |
|
debug ("Filtering kde-projects modules that don't have a $moduleSetBranch branch"); |
|
@xmlResults = grep { |
|
list_has($_->{'branches'}, $moduleSetBranch) |
|
} (@xmlResults); |
|
} |
|
|
|
if (!@xmlResults) { |
|
warning (" y[b[*] Module y[$moduleSearchItem] is apparently XML-based, but contains no\n" . |
|
"active modules to build!"); |
|
my $count = scalar @allXmlResults; |
|
if ($count > 0) { |
|
warning ("\tAlthough no active modules are available, there were\n" . |
|
"\t$count inactive modules. Perhaps the git modules are not ready?"); |
|
} |
|
} |
|
|
|
# Setup module options. |
|
my @moduleList; |
|
my @ignoreList = $self->modulesToIgnore(); |
|
|
|
foreach (@xmlResults) { |
|
my $result = $_; |
|
my $repo = $result->{'repo'}; |
|
|
|
# Prefer kde: alias to normal clone URL. |
|
$repo =~ s(^git://anongit\.kde\.org/)(kde:); |
|
|
|
my $newModule = ksb::Module->new($ctx, $result->{'name'}); |
|
$self->_initializeNewModule($newModule); |
|
$newModule->setOption('repository', $repo); |
|
$newModule->setOption('#xml-full-path', $result->{'fullName'}); |
|
$newModule->setOption('#branch:stable', $result->{'branch:stable'}); |
|
$newModule->setScmType('proj'); |
|
|
|
my $tarball = $result->{'tarball'}; |
|
$newModule->setOption('#snapshot-tarball', $tarball) if $tarball; |
|
|
|
if (none_true( |
|
map { |
|
ksb::KDEXMLReader::_projectPathMatchesWildcardSearch( |
|
$result->{'fullName'}, |
|
$_ |
|
) |
|
} (@ignoreList))) |
|
{ |
|
push @moduleList, $newModule; |
|
} |
|
else { |
|
debug ("--- Ignoring matched active module $newModule in module set " . |
|
$self->name()); |
|
} |
|
}; |
|
|
|
return @moduleList; |
|
} |
|
|
|
# This function should be called after options are read and build metadata is |
|
# available in order to convert this module set to a list of ksb::Module. |
|
# Any modules ignored by this module set are excluded from the returned list. |
|
# The modules returned have not been added to the build context. |
|
sub convertToModules |
|
{ |
|
my ($self, $ctx) = @_; |
|
|
|
my @moduleList; # module names converted to ksb::Module objects. |
|
my %foundModules; |
|
|
|
# Setup default options for each module |
|
# Extraction of relevant XML modules will be handled immediately after |
|
# this phase of execution. |
|
for my $moduleItem ($self->modulesToFind()) { |
|
# We might have already grabbed the right module recursively. |
|
next if exists $foundModules{$moduleItem}; |
|
|
|
# eval in case the XML processor throws an exception. |
|
undef $@; |
|
my @candidateModules = eval { |
|
$self->_expandModuleCandidates($ctx, $moduleItem); |
|
}; |
|
|
|
if ($@) { |
|
die $@ if had_an_exception(); # Forward exception objects up |
|
croak_runtime("The XML for the KDE Project database could not be understood: $@"); |
|
} |
|
|
|
my @moduleNames = map { $_->name() } @candidateModules; |
|
@foundModules{@moduleNames} = (1) x @moduleNames; |
|
push @moduleList, @candidateModules; |
|
} |
|
|
|
if (not scalar @moduleList) { |
|
warning ("No modules were defined for the module-set " . $self->name()); |
|
warning ("You should use the g[b[use-modules] option to make the module-set useful."); |
|
} |
|
|
|
return @moduleList; |
|
} |
|
|
|
1;
|
|
|