BuildProfiles.pm 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. # Copyright © 2013 Guillem Jover <guillem@debian.org>
  2. #
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. package Dpkg::BuildProfiles;
  16. use strict;
  17. use warnings;
  18. our $VERSION = '1.00';
  19. our @EXPORT_OK = qw(
  20. get_build_profiles
  21. set_build_profiles
  22. parse_build_profiles
  23. evaluate_restriction_formula
  24. );
  25. use Exporter qw(import);
  26. use Dpkg::Util qw(:list);
  27. use Dpkg::Build::Env;
  28. my $cache_profiles;
  29. my @build_profiles;
  30. =encoding utf8
  31. =head1 NAME
  32. Dpkg::BuildProfiles - handle build profiles
  33. =head1 DESCRIPTION
  34. The Dpkg::BuildProfiles module provides functions to handle the build
  35. profiles.
  36. =head1 FUNCTIONS
  37. =over 4
  38. =item @profiles = get_build_profiles()
  39. Get an array with the currently active build profiles, taken from
  40. the environment variable B<DEB_BUILD_PROFILES>.
  41. =cut
  42. sub get_build_profiles {
  43. return @build_profiles if $cache_profiles;
  44. if (Dpkg::Build::Env::has('DEB_BUILD_PROFILES')) {
  45. @build_profiles = split /\s+/, Dpkg::Build::Env::get('DEB_BUILD_PROFILES');
  46. }
  47. $cache_profiles = 1;
  48. return @build_profiles;
  49. }
  50. =item set_build_profiles(@profiles)
  51. Set C<@profiles> as the current active build profiles, by setting
  52. the environment variable B<DEB_BUILD_PROFILES>.
  53. =cut
  54. sub set_build_profiles {
  55. my (@profiles) = @_;
  56. $cache_profiles = 1;
  57. @build_profiles = @profiles;
  58. Dpkg::Build::Env::set('DEB_BUILD_PROFILES', join ' ', @profiles);
  59. }
  60. =item @profiles = parse_build_profiles($string)
  61. Parses a build profiles specification, into an array of array references.
  62. =cut
  63. sub parse_build_profiles {
  64. my $string = shift;
  65. $string =~ s/^\s*<\s*(.*)\s*>\s*$/$1/;
  66. return map { [ split /\s+/ ] } split /\s*>\s+<\s*/, $string;
  67. }
  68. =item evaluate_restriction_formula(\@formula, \@profiles)
  69. Evaluate whether a restriction formula of the form "<foo bar> <baz>", given as
  70. a nested array, is true or false, given the array of enabled build profiles.
  71. =cut
  72. sub evaluate_restriction_formula {
  73. my ($formula, $profiles) = @_;
  74. # Restriction formulas are in disjunctive normal form:
  75. # (foo AND bar) OR (blub AND bla)
  76. foreach my $restrlist (@{$formula}) {
  77. my $seen_profile = 1;
  78. foreach my $restriction (@$restrlist) {
  79. next if $restriction !~ m/^(!)?(.+)/;
  80. my $negated = defined $1 && $1 eq '!';
  81. my $profile = $2;
  82. my $found = any { $_ eq $profile } @{$profiles};
  83. # If a negative set profile is encountered, stop processing.
  84. # If a positive unset profile is encountered, stop processing.
  85. if ($found == $negated) {
  86. $seen_profile = 0;
  87. last;
  88. }
  89. }
  90. # This conjunction evaluated to true so we don't have to evaluate
  91. # the others.
  92. return 1 if $seen_profile;
  93. }
  94. return 0;
  95. }
  96. =back
  97. =head1 CHANGES
  98. =head2 Version 1.00 (dpkg 1.17.17)
  99. Mark the module as public.
  100. =cut
  101. 1;