[Notes] [Git][BuildStream/buildstream][Qinusty/600-recursive-variables] 15 commits: doc/source/conf.py: Fix E201, E202 warnings



Title: GitLab

Qinusty pushed to branch Qinusty/600-recursive-variables at BuildStream / buildstream

Commits:

26 changed files:

Changes:

  • .gitignore
    ... ... @@ -26,6 +26,7 @@ __pycache__/
    26 26
     buildstream/__version__.py
    
    27 27
     
    
    28 28
     # Autogenerated doc
    
    29
    +doc/source/badges/
    
    29 30
     doc/source/sessions/
    
    30 31
     doc/source/elements/
    
    31 32
     doc/source/sources/
    

  • .gitlab-ci.yml
    ... ... @@ -84,25 +84,25 @@ source_dist:
    84 84
         - coverage-linux/
    
    85 85
     
    
    86 86
     tests-debian-9:
    
    87
    -  image: buildstream/testsuite-debian:9-master-114-4cab18e3
    
    87
    +  image: buildstream/testsuite-debian:9-master-117-aa3a33b3
    
    88 88
       <<: *linux-tests
    
    89 89
     
    
    90 90
     tests-fedora-27:
    
    91
    -  image: buildstream/testsuite-fedora:27-master-114-4cab18e3
    
    91
    +  image: buildstream/testsuite-fedora:27-master-117-aa3a33b3
    
    92 92
       <<: *linux-tests
    
    93 93
     
    
    94 94
     tests-fedora-28:
    
    95
    -  image: buildstream/testsuite-fedora:28-master-114-4cab18e3
    
    95
    +  image: buildstream/testsuite-fedora:28-master-117-aa3a33b3
    
    96 96
       <<: *linux-tests
    
    97 97
     
    
    98 98
     tests-ubuntu-18.04:
    
    99
    -  image: buildstream/testsuite-ubuntu:18.04-master-114-4cab18e3
    
    99
    +  image: buildstream/testsuite-ubuntu:18.04-master-117-aa3a33b3
    
    100 100
       <<: *linux-tests
    
    101 101
     
    
    102 102
     tests-unix:
    
    103 103
       # Use fedora here, to a) run a test on fedora and b) ensure that we
    
    104 104
       # can get rid of ostree - this is not possible with debian-8
    
    105
    -  image: buildstream/testsuite-fedora:27-master-114-4cab18e3
    
    105
    +  image: buildstream/testsuite-fedora:27-master-117-aa3a33b3
    
    106 106
       stage: test
    
    107 107
       variables:
    
    108 108
         BST_FORCE_BACKEND: "unix"
    

  • README.rst
    1 1
     About
    
    2 2
     -----
    
    3
    +
    
    4
    +.. image:: https://buildstream.gitlab.io/buildstream/_static/release.svg
    
    5
    +   :target: https://gitlab.com/BuildStream/buildstream/commits/bst-1.2
    
    6
    +
    
    7
    +.. image:: https://buildstream.gitlab.io/buildstream/_static/snapshot.svg
    
    8
    +   :target: https://gitlab.com/BuildStream/buildstream/commits/master
    
    9
    +
    
    3 10
     .. image:: https://gitlab.com/BuildStream/buildstream/badges/master/pipeline.svg
    
    4 11
        :target: https://gitlab.com/BuildStream/buildstream/commits/master
    
    5 12
     
    

  • buildstream/_exceptions.py
    ... ... @@ -217,6 +217,9 @@ class LoadErrorReason(Enum):
    217 217
         # A recursive include has been encountered.
    
    218 218
         RECURSIVE_INCLUDE = 21
    
    219 219
     
    
    220
    +    # A recursive variable has been encountered
    
    221
    +    RECURSIVE_VARIABLE = 22
    
    222
    +
    
    220 223
     
    
    221 224
     # LoadError
    
    222 225
     #
    

  • buildstream/_variables.py
    ... ... @@ -61,7 +61,7 @@ class Variables():
    61 61
         #    LoadError, if the string contains unresolved variable references.
    
    62 62
         #
    
    63 63
         def subst(self, string):
    
    64
    -        substitute, unmatched = self._subst(string, self.variables)
    
    64
    +        substitute, unmatched, _ = self._subst(string, self.variables)
    
    65 65
             unmatched = list(set(unmatched))
    
    66 66
             if unmatched:
    
    67 67
                 if len(unmatched) == 1:
    
    ... ... @@ -82,6 +82,7 @@ class Variables():
    82 82
             def subst_callback(match):
    
    83 83
                 nonlocal variables
    
    84 84
                 nonlocal unmatched
    
    85
    +            nonlocal matched
    
    85 86
     
    
    86 87
                 token = match.group(0)
    
    87 88
                 varname = match.group(1)
    
    ... ... @@ -91,6 +92,7 @@ class Variables():
    91 92
                     # We have to check if the inner string has variables
    
    92 93
                     # and return unmatches for those
    
    93 94
                     unmatched += re.findall(_VARIABLE_MATCH, value)
    
    95
    +                matched += [varname]
    
    94 96
                 else:
    
    95 97
                     # Return unmodified token
    
    96 98
                     unmatched += [varname]
    
    ... ... @@ -98,10 +100,11 @@ class Variables():
    98 100
     
    
    99 101
                 return value
    
    100 102
     
    
    103
    +        matched = []
    
    101 104
             unmatched = []
    
    102 105
             replacement = re.sub(_VARIABLE_MATCH, subst_callback, string)
    
    103 106
     
    
    104
    -        return (replacement, unmatched)
    
    107
    +        return (replacement, unmatched, matched)
    
    105 108
     
    
    106 109
         # Variable resolving code
    
    107 110
         #
    
    ... ... @@ -131,7 +134,15 @@ class Variables():
    131 134
                     # Ensure stringness of the value before substitution
    
    132 135
                     value = _yaml.node_get(variables, str, key)
    
    133 136
     
    
    134
    -                resolved_var, item_unmatched = self._subst(value, variables)
    
    137
    +                resolved_var, item_unmatched, matched = self._subst(value, variables)
    
    138
    +
    
    139
    +                if _wrap_variable(key) in resolved_var:
    
    140
    +                    referenced_through = find_recursive_variable(key, matched, variables)
    
    141
    +                    raise LoadError(LoadErrorReason.RECURSIVE_VARIABLE,
    
    142
    +                                    "{}: ".format(_yaml.node_get_provenance(variables, key)) +
    
    143
    +                                    ("Variable '{}' expands to contain a reference to itself. " +
    
    144
    +                                     "Perhaps '{}' contains '{}").format(key, referenced_through, _wrap_variable(key)))
    
    145
    +
    
    135 146
                     resolved[key] = resolved_var
    
    136 147
                     unmatched += item_unmatched
    
    137 148
     
    
    ... ... @@ -168,8 +179,21 @@ class Variables():
    168 179
         # Helper function to fetch information about the node referring to a variable
    
    169 180
         #
    
    170 181
         def _find_references(self, varname):
    
    171
    -        fullname = '%{' + varname + '}'
    
    182
    +        fullname = _wrap_variable(varname)
    
    172 183
             for key, value in _yaml.node_items(self.original):
    
    173 184
                 if fullname in value:
    
    174 185
                     provenance = _yaml.node_get_provenance(self.original, key)
    
    175 186
                     yield (key, provenance)
    
    187
    +
    
    188
    +
    
    189
    +def find_recursive_variable(variable, matched_variables, all_vars):
    
    190
    +    matched_values = (_yaml.node_get(all_vars, str, key) for key in matched_variables)
    
    191
    +    for key, value in zip(matched_variables, matched_values):
    
    192
    +        if _wrap_variable(variable) in value:
    
    193
    +            return key
    
    194
    +    else:
    
    195
    +        return None
    
    196
    +
    
    197
    +
    
    198
    +def _wrap_variable(var):
    
    199
    +    return "%{" + var + "}"

  • buildstream/plugins/sources/tar.py
    ... ... @@ -127,7 +127,7 @@ class TarSource(DownloadableFileSource):
    127 127
             if not base_dir.endswith(os.sep):
    
    128 128
                 base_dir = base_dir + os.sep
    
    129 129
     
    
    130
    -        l = len(base_dir)
    
    130
    +        L = len(base_dir)
    
    131 131
             for member in tar.getmembers():
    
    132 132
     
    
    133 133
                 # First, ensure that a member never starts with `./`
    
    ... ... @@ -145,9 +145,9 @@ class TarSource(DownloadableFileSource):
    145 145
                     #       base directory.
    
    146 146
                     #
    
    147 147
                     if member.type == tarfile.LNKTYPE:
    
    148
    -                    member.linkname = member.linkname[l:]
    
    148
    +                    member.linkname = member.linkname[L:]
    
    149 149
     
    
    150
    -                member.path = member.path[l:]
    
    150
    +                member.path = member.path[L:]
    
    151 151
                     yield member
    
    152 152
     
    
    153 153
         # We want to iterate over all paths of a tarball, but getmembers()
    

  • buildstream/plugins/sources/zip.py
    ... ... @@ -121,13 +121,13 @@ class ZipSource(DownloadableFileSource):
    121 121
             if not base_dir.endswith(os.sep):
    
    122 122
                 base_dir = base_dir + os.sep
    
    123 123
     
    
    124
    -        l = len(base_dir)
    
    124
    +        L = len(base_dir)
    
    125 125
             for member in archive.infolist():
    
    126 126
                 if member.filename == base_dir:
    
    127 127
                     continue
    
    128 128
     
    
    129 129
                 if member.filename.startswith(base_dir):
    
    130
    -                member.filename = member.filename[l:]
    
    130
    +                member.filename = member.filename[L:]
    
    131 131
                     yield member
    
    132 132
     
    
    133 133
         # We want to iterate over all paths of an archive, but namelist()
    

  • buildstream/source.py
    ... ... @@ -219,10 +219,7 @@ class SourceFetcher():
    219 219
             Args:
    
    220 220
                url (str): The url used to download.
    
    221 221
             """
    
    222
    -        # Not guaranteed to be a valid alias yet.
    
    223
    -        # Ensuring it's a valid alias currently happens in Project.get_alias_uris
    
    224
    -        alias, _ = url.split(utils._ALIAS_SEPARATOR, 1)
    
    225
    -        self.__alias = alias
    
    222
    +        self.__alias = _extract_alias(url)
    
    226 223
     
    
    227 224
         #############################################################
    
    228 225
         #            Private Methods used in BuildStream            #
    
    ... ... @@ -459,8 +456,7 @@ class Source(Plugin):
    459 456
     
    
    460 457
             *Since: 1.2*
    
    461 458
             """
    
    462
    -        alias, _ = url.split(utils._ALIAS_SEPARATOR, 1)
    
    463
    -        self.__expected_alias = alias
    
    459
    +        self.__expected_alias = _extract_alias(url)
    
    464 460
     
    
    465 461
         def get_source_fetchers(self):
    
    466 462
             """Get the objects that are used for fetching
    
    ... ... @@ -525,8 +521,7 @@ class Source(Plugin):
    525 521
             else:
    
    526 522
                 # Sneakily store the alias if it hasn't already been stored
    
    527 523
                 if not self.__expected_alias and url and utils._ALIAS_SEPARATOR in url:
    
    528
    -                url_alias, _ = url.split(utils._ALIAS_SEPARATOR, 1)
    
    529
    -                self.__expected_alias = url_alias
    
    524
    +                self.mark_download_url(url)
    
    530 525
     
    
    531 526
                 project = self._get_project()
    
    532 527
                 return project.translate_url(url, first_pass=self.__first_pass)
    
    ... ... @@ -914,12 +909,12 @@ class Source(Plugin):
    914 909
         # Tries to call track for every mirror, stopping once it succeeds
    
    915 910
         def __do_track(self, **kwargs):
    
    916 911
             project = self._get_project()
    
    917
    -        # If there are no mirrors, or no aliases to replace, there's nothing to do here.
    
    918 912
             alias = self._get_alias()
    
    919 913
             if self.__first_pass:
    
    920 914
                 mirrors = project.first_pass_config.mirrors
    
    921 915
             else:
    
    922 916
                 mirrors = project.config.mirrors
    
    917
    +        # If there are no mirrors, or no aliases to replace, there's nothing to do here.
    
    923 918
             if not mirrors or not alias:
    
    924 919
                 return self.track(**kwargs)
    
    925 920
     
    
    ... ... @@ -988,3 +983,11 @@ class Source(Plugin):
    988 983
     
    
    989 984
                 if src.get_consistency() == Consistency.RESOLVED:
    
    990 985
                     src._fetch(previous_sources[0:index])
    
    986
    +
    
    987
    +
    
    988
    +def _extract_alias(url):
    
    989
    +    parts = url.split(utils._ALIAS_SEPARATOR, 1)
    
    990
    +    if len(parts) > 1 and not parts[0].lower() in utils._URI_SCHEMES:
    
    991
    +        return parts[0]
    
    992
    +    else:
    
    993
    +        return ""

  • buildstream/utils.py
    ... ... @@ -47,6 +47,7 @@ _magic_timestamp = calendar.timegm([2011, 11, 11, 11, 11, 11])
    47 47
     
    
    48 48
     # The separator we use for user specified aliases
    
    49 49
     _ALIAS_SEPARATOR = ':'
    
    50
    +_URI_SCHEMES = ["http", "https", "ftp", "file", "git", "sftp", "ssh"]
    
    50 51
     
    
    51 52
     
    
    52 53
     class UtilError(BstError):
    
    ... ... @@ -645,6 +646,7 @@ def _pretty_size(size, dec_places=0):
    645 646
                 psize /= 1024
    
    646 647
         return "{size:g}{unit}".format(size=round(psize, dec_places), unit=unit)
    
    647 648
     
    
    649
    +
    
    648 650
     # A sentinel to be used as a default argument for functions that need
    
    649 651
     # to distinguish between a kwarg set to None and an unset kwarg.
    
    650 652
     _sentinel = object()
    

  • dev-requirements.txt
    ... ... @@ -8,3 +8,4 @@ pytest-env
    8 8
     pytest-pep8
    
    9 9
     pytest-pylint
    
    10 10
     pytest-xdist
    
    11
    +pytest-timeout

  • doc/Makefile
    ... ... @@ -35,7 +35,7 @@ endif
    35 35
     PYTHONPATH=$(CURDIR)/..:$(CURDIR)/../buildstream/plugins
    
    36 36
     
    
    37 37
     
    
    38
    -.PHONY: all clean templates templates-clean sessions sessions-prep sessions-clean html devhelp
    
    38
    +.PHONY: all clean templates templates-clean sessions sessions-prep sessions-clean badges badges-clean html devhelp
    
    39 39
     
    
    40 40
     # Canned recipe for generating plugin api skeletons
    
    41 41
     #   $1 = the plugin directory
    
    ... ... @@ -70,9 +70,13 @@ endef
    70 70
     
    
    71 71
     all: html devhelp
    
    72 72
     
    
    73
    -clean: templates-clean sessions-clean
    
    73
    +clean: templates-clean sessions-clean badges-clean
    
    74 74
     	rm -rf build
    
    75 75
     
    
    76
    +############################################################
    
    77
    +#                 Plugin doc templates                     #
    
    78
    +############################################################
    
    79
    +
    
    76 80
     # Generate rst templates for the docs using a mix of sphinx-apidoc and
    
    77 81
     # our 'plugin-doc-skeleton' routine for plugin pages.
    
    78 82
     templates:
    
    ... ... @@ -86,6 +90,10 @@ templates-clean:
    86 90
     	rm -rf source/elements
    
    87 91
     	rm -rf source/sources
    
    88 92
     
    
    93
    +############################################################
    
    94
    +#                   Session captures                       #
    
    95
    +############################################################
    
    96
    +
    
    89 97
     # Stage the stored sessions into the place where they will
    
    90 98
     # be used in the build.
    
    91 99
     #
    
    ... ... @@ -111,10 +119,27 @@ sessions: sessions-prep
    111 119
     sessions-clean:
    
    112 120
     	rm -rf source/sessions
    
    113 121
     
    
    122
    +
    
    123
    +############################################################
    
    124
    +#                  Generate release badges                 #
    
    125
    +############################################################
    
    126
    +badges-clean:
    
    127
    +	rm -rf source/badges
    
    128
    +
    
    129
    +badges:
    
    130
    +	mkdir -p source/badges
    
    131
    +	$(CURDIR)/badges.py > source/badges/snapshot.svg
    
    132
    +	$(CURDIR)/badges.py --release > source/badges/release.svg
    
    133
    +
    
    134
    +
    
    135
    +############################################################
    
    136
    +#                    Main sphinx build                     #
    
    137
    +############################################################
    
    138
    +
    
    114 139
     # Targets which generate docs with sphinx build
    
    115 140
     #
    
    116 141
     #
    
    117
    -html devhelp: templates sessions
    
    142
    +html devhelp: templates sessions badges
    
    118 143
     	@echo "Building $@..."
    
    119 144
     	PYTHONPATH=$(PYTHONPATH) \
    
    120 145
     	    $(SPHINXBUILD) -b $@ $(ALLSPHINXOPTS) "$(BUILDDIR)/$@" \
    

  • doc/badges.py
    1
    +#!/usr/bin/env python3
    
    2
    +#
    
    3
    +#  Copyright (C) 2018 Codethink Limited
    
    4
    +#
    
    5
    +#  This program is free software; you can redistribute it and/or
    
    6
    +#  modify it under the terms of the GNU Lesser General Public
    
    7
    +#  License as published by the Free Software Foundation; either
    
    8
    +#  version 2 of the License, or (at your option) any later version.
    
    9
    +#
    
    10
    +#  This library is distributed in the hope that it will be useful,
    
    11
    +#  but WITHOUT ANY WARRANTY; without even the implied warranty of
    
    12
    +#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
    
    13
    +#  Lesser General Public License for more details.
    
    14
    +#
    
    15
    +#  You should have received a copy of the GNU Lesser General Public
    
    16
    +#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
    
    17
    +#
    
    18
    +#  Authors:
    
    19
    +#        Tristan Van Berkom <tristan vanberkom codethink co uk>
    
    20
    +#
    
    21
    +import click
    
    22
    +import subprocess
    
    23
    +import re
    
    24
    +
    
    25
    +# The badge template is modeled after the gitlab badge svgs
    
    26
    +#
    
    27
    +BADGE_TEMPLATE = """
    
    28
    +<svg xmlns="http://www.w3.org/2000/svg"
    
    29
    +     xmlns:xlink="http://www.w3.org/1999/xlink"
    
    30
    +     width="116" height="20">
    
    31
    +  <a xlink:href="">
    
    32
    +    <linearGradient id="{badge_name}_b" x2="0" y2="100%">
    
    33
    +      <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
    
    34
    +      <stop offset="1" stop-opacity=".1"/>
    
    35
    +    </linearGradient>
    
    36
    +
    
    37
    +    <mask id="{badge_name}_a">
    
    38
    +      <rect width="116" height="20" rx="3" fill="#fff"/>
    
    39
    +    </mask>
    
    40
    +
    
    41
    +    <g mask="url(#{badge_name}_a)">
    
    42
    +      <path fill="#555"
    
    43
    +            d="M0 0 h62 v20 H0 z"/>
    
    44
    +      <path fill="{color}"
    
    45
    +            d="M62 0 h54 v20 H62 z"/>
    
    46
    +      <path fill="url(#{badge_name}_b)"
    
    47
    +            d="M0 0 h116 v20 H0 z"/>
    
    48
    +    </g>
    
    49
    +
    
    50
    +    <g fill="#fff" text-anchor="middle">
    
    51
    +      <g font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
    
    52
    +        <text x="31" y="15" fill="#010101" fill-opacity=".3">
    
    53
    +          {badge_name}
    
    54
    +        </text>
    
    55
    +        <text x="31" y="14">
    
    56
    +          {badge_name}
    
    57
    +        </text>
    
    58
    +        <text x="89" y="15" fill="#010101" fill-opacity=".3">
    
    59
    +          {version}
    
    60
    +        </text>
    
    61
    +        <text x="89" y="14">
    
    62
    +          {version}
    
    63
    +        </text>
    
    64
    +      </g>
    
    65
    +    </g>
    
    66
    +  </a>
    
    67
    +</svg>
    
    68
    +"""
    
    69
    +
    
    70
    +URL_FORMAT = 'https://download.gnome.org/sources/BuildStream/{brief_version}/BuildStream-{full_version}.tar.xz'
    
    71
    +RELEASE_COLOR = '#0040FF'
    
    72
    +SNAPSHOT_COLOR = '#FF8000'
    
    73
    +VERSION_TAG_MATCH = r'([0-9]*)\.([0-9]*)\.([0-9]*)'
    
    74
    +
    
    75
    +
    
    76
    +# Parse a release tag and return a three tuple
    
    77
    +# of the major, minor and micro version.
    
    78
    +#
    
    79
    +# Tags which do not follow the release tag format
    
    80
    +# will just be returned as (0, 0, 0)
    
    81
    +#
    
    82
    +def parse_tag(tag):
    
    83
    +    match = re.search(VERSION_TAG_MATCH, tag)
    
    84
    +    if match:
    
    85
    +        major = match.group(1)
    
    86
    +        minor = match.group(2)
    
    87
    +        micro = match.group(3)
    
    88
    +        return (int(major), int(minor), int(micro))
    
    89
    +
    
    90
    +    return (0, 0, 0)
    
    91
    +
    
    92
    +
    
    93
    +# Call out to git and guess the latest version,
    
    94
    +# this will just return (0, 0, 0) in case of any error.
    
    95
    +#
    
    96
    +def guess_version(release):
    
    97
    +    try:
    
    98
    +        tags_output = subprocess.check_output(['git', 'tag'])
    
    99
    +    except CalledProcessError:
    
    100
    +        return (0, 0, 0)
    
    101
    +
    
    102
    +    # Parse the `git tag` output into a list of integer tuples
    
    103
    +    tags_output = tags_output.decode('UTF-8')
    
    104
    +    all_tags = tags_output.splitlines()
    
    105
    +    all_versions = [parse_tag(tag) for tag in all_tags]
    
    106
    +
    
    107
    +    # Filter the list by the minor point version, if
    
    108
    +    # we are checking for the latest "release" version, then
    
    109
    +    # only pickup even number minor points.
    
    110
    +    #
    
    111
    +    filtered_versions = [
    
    112
    +        version for version in all_versions
    
    113
    +        if (version[1] % 2) == (not release)
    
    114
    +    ]
    
    115
    +
    
    116
    +    # Make sure they are sorted, and take the last one
    
    117
    +    sorted_versions = sorted(filtered_versions)
    
    118
    +    latest_version = sorted_versions[-1]
    
    119
    +
    
    120
    +    return latest_version
    
    121
    +
    
    122
    +
    
    123
    +@click.command(short_help="Generate the version badges")
    
    124
    +@click.option('--release', is_flag=True, default=False,
    
    125
    +              help="Whether to generate the badge for the release version")
    
    126
    +def generate_badges(release):
    
    127
    +    """Generate the version badge svg files
    
    128
    +    """
    
    129
    +    major, minor, micro = guess_version(release)
    
    130
    +
    
    131
    +    if release:
    
    132
    +        badge_name = 'release'
    
    133
    +        color = RELEASE_COLOR
    
    134
    +    else:
    
    135
    +        badge_name = 'snapshot'
    
    136
    +        color = SNAPSHOT_COLOR
    
    137
    +
    
    138
    +    brief_version = '{major}.{minor}'.format(major=major, minor=minor)
    
    139
    +    full_version = '{major}.{minor}.{micro}'.format(major=major, minor=minor, micro=micro)
    
    140
    +    url_target = URL_FORMAT.format(brief_version=brief_version, full_version=full_version)
    
    141
    +    badge = BADGE_TEMPLATE.format(badge_name=badge_name,
    
    142
    +                                  version=full_version,
    
    143
    +                                  color=color,
    
    144
    +                                  url_target=url_target)
    
    145
    +    click.echo(badge, nl=False)
    
    146
    +    return 0
    
    147
    +
    
    148
    +
    
    149
    +if __name__ == '__main__':
    
    150
    +    generate_badges()

  • doc/bst2html.py
    ... ... @@ -96,8 +96,8 @@ def _ansi2html_get_styles(palette):
    96 96
     
    
    97 97
             for g in range(24):
    
    98 98
                 i = g + 232
    
    99
    -            l = g * 10 + 8
    
    100
    -            indexed_style['%s' % i] = ''.join('%02X' % c if 0 <= c <= 255 else None for c in (l, l, l))
    
    99
    +            L = g * 10 + 8
    
    100
    +            indexed_style['%s' % i] = ''.join('%02X' % c if 0 <= c <= 255 else None for c in (L, L, L))
    
    101 101
     
    
    102 102
             _ANSI2HTML_STYLES[palette] = (regular_style, bold_style, indexed_style)
    
    103 103
         return _ANSI2HTML_STYLES[palette]
    
    ... ... @@ -455,6 +455,7 @@ def run_bst(directory, force, source_cache, description, palette):
    455 455
     
    
    456 456
         return 0
    
    457 457
     
    
    458
    +
    
    458 459
     if __name__ == '__main__':
    
    459 460
         try:
    
    460 461
             run_bst()
    

  • doc/source/conf.py
    ... ... @@ -19,10 +19,10 @@
    19 19
     #
    
    20 20
     import os
    
    21 21
     import sys
    
    22
    -sys.path.insert(0, os.path.abspath('..'))
    
    23
    -
    
    24 22
     from buildstream import __version__
    
    25 23
     
    
    24
    +sys.path.insert(0, os.path.abspath('..'))
    
    25
    +
    
    26 26
     # -- General configuration ------------------------------------------------
    
    27 27
     
    
    28 28
     # If your documentation needs a minimal Sphinx version, state it here.
    
    ... ... @@ -112,7 +112,7 @@ add_module_names = False
    112 112
     pygments_style = 'sphinx'
    
    113 113
     
    
    114 114
     # A list of ignored prefixes for module index sorting.
    
    115
    -modindex_common_prefix = [ 'buildstream.' ]
    
    115
    +modindex_common_prefix = ['buildstream.']
    
    116 116
     
    
    117 117
     # If true, keep warnings as "system message" paragraphs in the built documents.
    
    118 118
     # keep_warnings = False
    
    ... ... @@ -160,7 +160,7 @@ html_theme = 'sphinx_rtd_theme'
    160 160
     # Add any paths that contain custom static files (such as style sheets) here,
    
    161 161
     # relative to this directory. They are copied after the builtin static files,
    
    162 162
     # so a file named "default.css" will overwrite the builtin "default.css".
    
    163
    -html_static_path = []
    
    163
    +html_static_path = ['badges']
    
    164 164
     
    
    165 165
     # Add any extra paths that contain custom files (such as robots.txt or
    
    166 166
     # .htaccess) here, relative to this directory. These files are copied
    

  • doc/source/install_versions.rst
    ... ... @@ -13,8 +13,12 @@ For example, for a given version number ``X.Y.Z``
    13 13
      * The ``X.<odd number>.*`` versions are development spanshots intended for testing.
    
    14 14
     
    
    15 15
     If you are :ref:`installing from git <install_git_checkout>`, please look for the latest
    
    16
    -tag in the latest release branch to ensure you're getting the latest release.
    
    16
    +tag to ensure you're getting the latest release.
    
    17 17
     
    
    18
    -Current release branches:
    
    19
    - * `bst-1.2 (latest) <https://gitlab.com/BuildStream/buildstream/commits/bst-1.2>`_
    
    20
    - * `bst-1.0 (deprecated) <https://gitlab.com/BuildStream/buildstream/commits/bst-1.0>`_
    18
    +* Latest release:
    
    19
    +
    
    20
    +  .. include:: release-badge.rst
    
    21
    +
    
    22
    +* Latest development snapshot:
    
    23
    +
    
    24
    +  .. include:: snapshot-badge.rst

  • doc/source/main_install.rst
    ... ... @@ -4,6 +4,11 @@
    4 4
     
    
    5 5
     Install
    
    6 6
     =======
    
    7
    +
    
    8
    +.. include:: release-badge.rst
    
    9
    +
    
    10
    +.. include:: snapshot-badge.rst
    
    11
    +
    
    7 12
     This section provides instructions for installing BuildStream and its
    
    8 13
     companion artifact server on various platforms, along with any installation
    
    9 14
     related materials.
    

  • doc/source/release-badge.rst
    1
    +
    
    2
    +.. Use this file to include the badge in the documentation, but not in
    
    3
    +   the README.rst or gitlab rendered materials, that doesnt work.
    
    4
    +
    
    5
    +   This is partly a workaround for a sphinx issue, we will be able
    
    6
    +   to avoid the raw html once this is implemented in sphinx:
    
    7
    +
    
    8
    +       https://github.com/sphinx-doc/sphinx/issues/2240
    
    9
    +
    
    10
    +   Using the <object> tag instead of the <img> tag which sphinx generates
    
    11
    +   allows the svg to be "interactive", for us this basically means that
    
    12
    +   the link we encode in the badge svg is used, rather than static urls
    
    13
    +   which need to be used around the <img> tag.
    
    14
    +
    
    15
    +   WARNING: The custom CSS on the style tag will need to change if we
    
    16
    +            change the theme, so that the <object> tag behaves similar
    
    17
    +	    to how the <img> tag is themed by the style sheets.
    
    18
    +
    
    19
    +.. raw:: html
    
    20
    +
    
    21
    +   <a class="reference external image-reference">
    
    22
    +     <object style="margin-bottom:24px;vertical-align:middle"
    
    23
    +             data=""
    
    24
    +	     type="image/svg+xml"/>
    
    25
    +     </object>
    
    26
    +   </a>

  • doc/source/snapshot-badge.rst
    1
    +
    
    2
    +.. Use this file to include the badge in the documentation, but not in
    
    3
    +   the README.rst or gitlab rendered materials, that doesnt work.
    
    4
    +
    
    5
    +   This is partly a workaround for a sphinx issue, we will be able
    
    6
    +   to avoid the raw html once this is implemented in sphinx:
    
    7
    +
    
    8
    +       https://github.com/sphinx-doc/sphinx/issues/2240
    
    9
    +
    
    10
    +   Using the <object> tag instead of the <img> tag which sphinx generates
    
    11
    +   allows the svg to be "interactive", for us this basically means that
    
    12
    +   the link we encode in the badge svg is used, rather than static urls
    
    13
    +   which need to be used around the <img> tag.
    
    14
    +
    
    15
    +   WARNING: The custom CSS on the style tag will need to change if we
    
    16
    +            change the theme, so that the <object> tag behaves similar
    
    17
    +	    to how the <img> tag is themed by the style sheets.
    
    18
    +
    
    19
    +.. raw:: html
    
    20
    +
    
    21
    +   <a class="reference external image-reference">
    
    22
    +     <object style="margin-bottom:24px;vertical-align:middle"
    
    23
    +             data=""
    
    24
    +	     type="image/svg+xml"/>
    
    25
    +     </object>
    
    26
    +   </a>

  • setup.py
    ... ... @@ -25,7 +25,14 @@ import subprocess
    25 25
     import sys
    
    26 26
     import versioneer
    
    27 27
     
    
    28
    -if sys.version_info[0] != 3 or sys.version_info[1] < 5:
    
    28
    +
    
    29
    +##################################################################
    
    30
    +# Python requirements
    
    31
    +##################################################################
    
    32
    +REQUIRED_PYTHON_MAJOR = 3
    
    33
    +REQUIRED_PYTHON_MINOR = 5
    
    34
    +
    
    35
    +if sys.version_info[0] != REQUIRED_PYTHON_MAJOR or sys.version_info[1] < REQUIRED_PYTHON_MINOR:
    
    29 36
         print("BuildStream requires Python >= 3.5")
    
    30 37
         sys.exit(1)
    
    31 38
     
    
    ... ... @@ -242,11 +249,28 @@ setup(name='BuildStream',
    242 249
     
    
    243 250
           author='BuildStream Developers',
    
    244 251
           author_email='buildstream-list gnome org',
    
    252
    +      classifiers=[
    
    253
    +          'Environment :: Console',
    
    254
    +          'Intended Audience :: Developers',
    
    255
    +          'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
    
    256
    +          'Operating System :: POSIX',
    
    257
    +          'Programming Language :: Python :: 3',
    
    258
    +          'Programming Language :: Python :: 3.5',
    
    259
    +          'Programming Language :: Python :: 3.6',
    
    260
    +          'Programming Language :: Python :: 3.7',
    
    261
    +          'Topic :: Software Development :: Build Tools'
    
    262
    +      ],
    
    245 263
           description='A framework for modelling build pipelines in YAML',
    
    246 264
           license='LGPL',
    
    247 265
           long_description=long_description,
    
    248 266
           long_description_content_type='text/x-rst; charset=UTF-8',
    
    249 267
           url='https://gitlab.com/BuildStream/buildstream',
    
    268
    +      project_urls={
    
    269
    +          'Documentation': 'https://buildstream.gitlab.io/buildstream/',
    
    270
    +          'Tracker': 'https://gitlab.com/BuildStream/buildstream/issues',
    
    271
    +          'Mailing List': 'https://mail.gnome.org/mailman/listinfo/buildstream-list'
    
    272
    +      },
    
    273
    +      python_requires='~={}.{}'.format(REQUIRED_PYTHON_MAJOR, REQUIRED_PYTHON_MINOR),
    
    250 274
           packages=find_packages(exclude=('tests', 'tests.*')),
    
    251 275
           package_data={'buildstream': ['plugins/*/*.py', 'plugins/*/*.yaml',
    
    252 276
                                         'data/*.yaml', 'data/*.sh.in']},
    

  • tests/cachekey/cachekey.py
    ... ... @@ -129,6 +129,7 @@ def assert_cache_keys(project_dir, output):
    129 129
                                  "Use tests/cachekey/update.py to automatically " +
    
    130 130
                                  "update this test case")
    
    131 131
     
    
    132
    +
    
    132 133
     ##############################################
    
    133 134
     #             Test Entry Point               #
    
    134 135
     ##############################################
    

  • tests/cachekey/update.py
    ... ... @@ -65,5 +65,6 @@ def update_keys():
    65 65
     
    
    66 66
                     write_expected_key(element_name, actual_keys[element_name])
    
    67 67
     
    
    68
    +
    
    68 69
     if __name__ == '__main__':
    
    69 70
         update_keys()

  • tests/format/variables.py
    1 1
     import os
    
    2 2
     import pytest
    
    3
    +import sys
    
    3 4
     from buildstream import _yaml
    
    4 5
     from buildstream._exceptions import ErrorDomain, LoadErrorReason
    
    5 6
     from tests.testutils.runcli import cli
    
    ... ... @@ -72,3 +73,20 @@ def test_missing_variable(cli, datafiles, tmpdir):
    72 73
         ])
    
    73 74
         result.assert_main_error(ErrorDomain.LOAD,
    
    74 75
                                  LoadErrorReason.UNRESOLVED_VARIABLE)
    
    76
    +
    
    77
    +@pytest.mark.timeout(3, method="signal")
    
    78
    +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'cyclic_variables'))
    
    79
    +def test_cyclic_variables(cli, datafiles):
    
    80
    +    print_warning("Performing cyclic test, if this test times out it will " +
    
    81
    +                  "exit the test sequence")
    
    82
    +    project = os.path.join(datafiles.dirname, datafiles.basename)
    
    83
    +    result = cli.run(project=project, silent=True, args=[
    
    84
    +        "build", "cyclic.bst"
    
    85
    +    ])
    
    86
    +    result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.RECURSIVE_VARIABLE)
    
    87
    +
    
    88
    +
    
    89
    +def print_warning(msg):
    
    90
    +    RED, END = "\033[91m", "\033[0m"
    
    91
    +    print(("\n{}{}{}").format(RED, msg, END), file=sys.stderr)
    
    92
    +

  • tests/format/variables/cyclic_variables/cyclic.bst
    1
    +kind: manual
    
    2
    +
    
    3
    +variables:
    
    4
    +  a: "%{prefix}/a"
    
    5
    +  prefix: "%{a}/some_prefix/"
    \ No newline at end of file

  • tests/format/variables/cyclic_variables/project.conf
    1
    +name: test

  • tests/frontend/buildcheckout.py
    ... ... @@ -288,6 +288,7 @@ def test_build_checkout_force_tarball(datafiles, cli):
    288 288
         assert os.path.join('.', 'usr', 'bin', 'hello') in tar.getnames()
    
    289 289
         assert os.path.join('.', 'usr', 'include', 'pony.h') in tar.getnames()
    
    290 290
     
    
    291
    +
    
    291 292
     fetch_build_checkout_combos = \
    
    292 293
         [("strict", kind) for kind in ALL_REPO_KINDS] + \
    
    293 294
         [("non-strict", kind) for kind in ALL_REPO_KINDS]
    

  • tests/testutils/runcli.py
    ... ... @@ -94,14 +94,28 @@ class Result():
    94 94
         #    error_reason (any): The reason field of the error which occurred
    
    95 95
         #    fail_message (str): An optional message to override the automatic
    
    96 96
         #                        assertion error messages
    
    97
    +    #    debug (bool): If true, prints information regarding the exit state of the result()
    
    97 98
         # Raises:
    
    98 99
         #    (AssertionError): If any of the assertions fail
    
    99 100
         #
    
    100 101
         def assert_main_error(self,
    
    101 102
                               error_domain,
    
    102 103
                               error_reason,
    
    103
    -                          fail_message=''):
    
    104
    -
    
    104
    +                          fail_message='',
    
    105
    +                          *, debug=False):
    
    106
    +        if debug:
    
    107
    +            print(
    
    108
    +                """
    
    109
    +                Exit code: {}
    
    110
    +                Exception: {}
    
    111
    +                Domain:    {}
    
    112
    +                Reason:    {}
    
    113
    +                """.format(
    
    114
    +                    self.exit_code,
    
    115
    +                    self.exception,
    
    116
    +                    self.exception.domain,
    
    117
    +                    self.exception.reason
    
    118
    +                ))
    
    105 119
             assert self.exit_code == -1, fail_message
    
    106 120
             assert self.exc is not None, fail_message
    
    107 121
             assert self.exception is not None, fail_message
    



  • [Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]