Tom Pollard pushed to branch tpollard/483 at BuildStream / buildstream
Commits:
-
10eeb503
by Javier Jardón at 2018-08-28T22:22:00Z
-
d3c32ca2
by Javier Jardón at 2018-08-28T22:22:00Z
-
3ae5fd05
by Javier Jardón at 2018-08-28T22:22:00Z
-
c6fb5ba7
by Javier Jardón at 2018-08-28T22:22:00Z
-
c5eca59d
by Tristan Van Berkom at 2018-08-29T10:45:33Z
-
63c6ee72
by Tristan Van Berkom at 2018-08-29T10:46:30Z
-
2d527052
by Tristan Van Berkom at 2018-08-29T10:46:30Z
-
29e7eea8
by Tristan Van Berkom at 2018-08-29T10:46:30Z
-
5d508779
by Tristan Van Berkom at 2018-08-29T11:13:53Z
-
8c95f225
by Tom Pollard at 2018-08-29T11:49:18Z
-
ffedce75
by Tom Pollard at 2018-08-29T11:49:18Z
18 changed files:
- .gitignore
- README.rst
- buildstream/plugins/sources/git.py
- buildstream/plugins/sources/tar.py
- buildstream/plugins/sources/zip.py
- buildstream/utils.py
- doc/Makefile
- + doc/badges.py
- doc/bst2html.py
- doc/source/conf.py
- doc/source/install_versions.rst
- doc/source/main_install.rst
- + doc/source/release-badge.rst
- + doc/source/snapshot-badge.rst
- tests/cachekey/cachekey.py
- tests/cachekey/update.py
- tests/frontend/buildcheckout.py
- tests/sources/git.py
Changes:
... | ... | @@ -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/
|
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 |
|
... | ... | @@ -74,6 +74,9 @@ This plugin provides the following configurable warnings: |
74 | 74 |
|
75 | 75 |
- 'git:inconsistent-submodule' - A submodule was found to be missing from the underlying git repository.
|
76 | 76 |
|
77 |
+This plugin also utilises the following configurable core plugin warnings:
|
|
78 |
+ |
|
79 |
+- 'ref-not-in-track' - The provided ref was not found in the provided track in the element's git repository.
|
|
77 | 80 |
"""
|
78 | 81 |
|
79 | 82 |
import os
|
... | ... | @@ -87,6 +90,7 @@ from configparser import RawConfigParser |
87 | 90 |
|
88 | 91 |
from buildstream import Source, SourceError, Consistency, SourceFetcher
|
89 | 92 |
from buildstream import utils
|
93 |
+from buildstream.plugin import CoreWarnings
|
|
90 | 94 |
|
91 | 95 |
GIT_MODULES = '.gitmodules'
|
92 | 96 |
|
... | ... | @@ -199,7 +203,7 @@ class GitMirror(SourceFetcher): |
199 | 203 |
cwd=self.mirror)
|
200 | 204 |
return output.rstrip('\n')
|
201 | 205 |
|
202 |
- def stage(self, directory):
|
|
206 |
+ def stage(self, directory, track=None):
|
|
203 | 207 |
fullpath = os.path.join(directory, self.path)
|
204 | 208 |
|
205 | 209 |
# Using --shared here avoids copying the objects into the checkout, in any
|
... | ... | @@ -213,10 +217,14 @@ class GitMirror(SourceFetcher): |
213 | 217 |
fail="Failed to checkout git ref {}".format(self.ref),
|
214 | 218 |
cwd=fullpath)
|
215 | 219 |
|
220 |
+ # Check that the user specified ref exists in the track if provided & not already tracked
|
|
221 |
+ if track:
|
|
222 |
+ self.assert_ref_in_track(fullpath, track)
|
|
223 |
+ |
|
216 | 224 |
# Remove .git dir
|
217 | 225 |
shutil.rmtree(os.path.join(fullpath, ".git"))
|
218 | 226 |
|
219 |
- def init_workspace(self, directory):
|
|
227 |
+ def init_workspace(self, directory, track=None):
|
|
220 | 228 |
fullpath = os.path.join(directory, self.path)
|
221 | 229 |
url = self.source.translate_url(self.url)
|
222 | 230 |
|
... | ... | @@ -232,6 +240,10 @@ class GitMirror(SourceFetcher): |
232 | 240 |
fail="Failed to checkout git ref {}".format(self.ref),
|
233 | 241 |
cwd=fullpath)
|
234 | 242 |
|
243 |
+ # Check that the user specified ref exists in the track if provided & not already tracked
|
|
244 |
+ if track:
|
|
245 |
+ self.assert_ref_in_track(fullpath, track)
|
|
246 |
+ |
|
235 | 247 |
# List the submodules (path/url tuples) present at the given ref of this repo
|
236 | 248 |
def submodule_list(self):
|
237 | 249 |
modules = "{}:{}".format(self.ref, GIT_MODULES)
|
... | ... | @@ -296,6 +308,28 @@ class GitMirror(SourceFetcher): |
296 | 308 |
|
297 | 309 |
return None
|
298 | 310 |
|
311 |
+ # Assert that ref exists in track, if track has been specified.
|
|
312 |
+ def assert_ref_in_track(self, fullpath, track):
|
|
313 |
+ _, branch = self.source.check_output([self.source.host_git, 'branch', '--list', track,
|
|
314 |
+ '--contains', self.ref],
|
|
315 |
+ cwd=fullpath,)
|
|
316 |
+ if branch:
|
|
317 |
+ return True
|
|
318 |
+ else:
|
|
319 |
+ _, tag = self.source.check_output([self.source.host_git, 'tag', '--list', track,
|
|
320 |
+ '--contains', self.ref],
|
|
321 |
+ cwd=fullpath,)
|
|
322 |
+ if tag:
|
|
323 |
+ return True
|
|
324 |
+ |
|
325 |
+ detail = "The ref provided for the element does not exist locally in the provided track branch / tag " + \
|
|
326 |
+ "'{}'.\nYou may wish to track the element to update the ref from '{}' ".format(track, track) + \
|
|
327 |
+ "with `bst track`,\nor examine the upstream at '{}' for the specific ref.".format(self.url)
|
|
328 |
+ |
|
329 |
+ self.source.warn("{}: expected ref '{}' was not found in given track '{}' for staged repository: '{}'\n"
|
|
330 |
+ .format(self.source, self.ref, track, self.url),
|
|
331 |
+ detail=detail, warning_token=CoreWarnings.REF_NOT_IN_TRACK)
|
|
332 |
+ |
|
299 | 333 |
|
300 | 334 |
class GitSource(Source):
|
301 | 335 |
# pylint: disable=attribute-defined-outside-init
|
... | ... | @@ -333,6 +367,7 @@ class GitSource(Source): |
333 | 367 |
self.submodule_checkout_overrides[path] = checkout
|
334 | 368 |
|
335 | 369 |
self.mark_download_url(self.original_url)
|
370 |
+ self.tracked = False
|
|
336 | 371 |
|
337 | 372 |
def preflight(self):
|
338 | 373 |
# Check if git is installed, get the binary at the same time
|
... | ... | @@ -396,6 +431,8 @@ class GitSource(Source): |
396 | 431 |
# Update self.mirror.ref and node.ref from the self.tracking branch
|
397 | 432 |
ret = self.mirror.latest_commit(self.tracking)
|
398 | 433 |
|
434 |
+ # Set tracked attribute, parameter for if self.mirror.assert_ref_in_track is needed
|
|
435 |
+ self.tracked = True
|
|
399 | 436 |
return ret
|
400 | 437 |
|
401 | 438 |
def init_workspace(self, directory):
|
... | ... | @@ -403,7 +440,7 @@ class GitSource(Source): |
403 | 440 |
self.refresh_submodules()
|
404 | 441 |
|
405 | 442 |
with self.timed_activity('Setting up workspace "{}"'.format(directory), silent_nested=True):
|
406 |
- self.mirror.init_workspace(directory)
|
|
443 |
+ self.mirror.init_workspace(directory, track=(self.tracking if not self.tracked else None))
|
|
407 | 444 |
for mirror in self.submodules:
|
408 | 445 |
mirror.init_workspace(directory)
|
409 | 446 |
|
... | ... | @@ -419,7 +456,7 @@ class GitSource(Source): |
419 | 456 |
# Stage the main repo in the specified directory
|
420 | 457 |
#
|
421 | 458 |
with self.timed_activity("Staging {}".format(self.mirror.url), silent_nested=True):
|
422 |
- self.mirror.stage(directory)
|
|
459 |
+ self.mirror.stage(directory, track=(self.tracking if not self.tracked else None))
|
|
423 | 460 |
for mirror in self.submodules:
|
424 | 461 |
if mirror.path in self.submodule_checkout_overrides:
|
425 | 462 |
checkout = self.submodule_checkout_overrides[mirror.path]
|
... | ... | @@ -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()
|
... | ... | @@ -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()
|
... | ... | @@ -645,6 +645,7 @@ def _pretty_size(size, dec_places=0): |
645 | 645 |
psize /= 1024
|
646 | 646 |
return "{size:g}{unit}".format(size=round(psize, dec_places), unit=unit)
|
647 | 647 |
|
648 |
+ |
|
648 | 649 |
# A sentinel to be used as a default argument for functions that need
|
649 | 650 |
# to distinguish between a kwarg set to None and an unset kwarg.
|
650 | 651 |
_sentinel = object()
|
... | ... | @@ -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)/$@" \
|
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()
|
... | ... | @@ -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()
|
... | ... | @@ -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
|
... | ... | @@ -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
|
... | ... | @@ -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.
|
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>
|
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>
|
... | ... | @@ -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 |
##############################################
|
... | ... | @@ -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()
|
... | ... | @@ -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]
|
... | ... | @@ -25,6 +25,7 @@ import pytest |
25 | 25 |
|
26 | 26 |
from buildstream._exceptions import ErrorDomain
|
27 | 27 |
from buildstream import _yaml
|
28 |
+from buildstream.plugin import CoreWarnings
|
|
28 | 29 |
|
29 | 30 |
from tests.testutils import cli, create_repo
|
30 | 31 |
from tests.testutils.site import HAVE_GIT
|
... | ... | @@ -408,3 +409,70 @@ def test_submodule_track_no_ref_or_track(cli, tmpdir, datafiles): |
408 | 409 |
result = cli.run(project=project, args=['show', 'target.bst'])
|
409 | 410 |
result.assert_main_error(ErrorDomain.SOURCE, "missing-track-and-ref")
|
410 | 411 |
result.assert_task_error(None, None)
|
412 |
+ |
|
413 |
+ |
|
414 |
+@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")
|
|
415 |
+@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template'))
|
|
416 |
+def test_ref_not_in_track_warn(cli, tmpdir, datafiles):
|
|
417 |
+ project = os.path.join(datafiles.dirname, datafiles.basename)
|
|
418 |
+ |
|
419 |
+ # Create the repo from 'repofiles', create a branch without latest commit
|
|
420 |
+ repo = create_repo('git', str(tmpdir))
|
|
421 |
+ ref = repo.create(os.path.join(project, 'repofiles'))
|
|
422 |
+ |
|
423 |
+ gitsource = repo.source_config(ref=ref)
|
|
424 |
+ |
|
425 |
+ # Overwrite the track value to the added branch
|
|
426 |
+ gitsource['track'] = 'foo'
|
|
427 |
+ |
|
428 |
+ # Write out our test target
|
|
429 |
+ element = {
|
|
430 |
+ 'kind': 'import',
|
|
431 |
+ 'sources': [
|
|
432 |
+ gitsource
|
|
433 |
+ ]
|
|
434 |
+ }
|
|
435 |
+ _yaml.dump(element, os.path.join(project, 'target.bst'))
|
|
436 |
+ |
|
437 |
+ # Assert the warning is raised as ref is not in branch foo.
|
|
438 |
+ # Assert warning not error to the user, when not set as fatal.
|
|
439 |
+ result = cli.run(project=project, args=['build', 'target.bst'])
|
|
440 |
+ assert "The ref provided for the element does not exist locally" in result.stderr
|
|
441 |
+ |
|
442 |
+ |
|
443 |
+@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")
|
|
444 |
+@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template'))
|
|
445 |
+def test_ref_not_in_track_warn_error(cli, tmpdir, datafiles):
|
|
446 |
+ project = os.path.join(datafiles.dirname, datafiles.basename)
|
|
447 |
+ |
|
448 |
+ # Add fatal-warnings ref-not-in-track to project.conf
|
|
449 |
+ project_template = {
|
|
450 |
+ "name": "foo",
|
|
451 |
+ "fatal-warnings": [CoreWarnings.REF_NOT_IN_TRACK]
|
|
452 |
+ }
|
|
453 |
+ |
|
454 |
+ _yaml.dump(project_template, os.path.join(project, 'project.conf'))
|
|
455 |
+ |
|
456 |
+ # Create the repo from 'repofiles', create a branch without latest commit
|
|
457 |
+ repo = create_repo('git', str(tmpdir))
|
|
458 |
+ ref = repo.create(os.path.join(project, 'repofiles'))
|
|
459 |
+ |
|
460 |
+ gitsource = repo.source_config(ref=ref)
|
|
461 |
+ |
|
462 |
+ # Overwrite the track value to the added branch
|
|
463 |
+ gitsource['track'] = 'foo'
|
|
464 |
+ |
|
465 |
+ # Write out our test target
|
|
466 |
+ element = {
|
|
467 |
+ 'kind': 'import',
|
|
468 |
+ 'sources': [
|
|
469 |
+ gitsource
|
|
470 |
+ ]
|
|
471 |
+ }
|
|
472 |
+ _yaml.dump(element, os.path.join(project, 'target.bst'))
|
|
473 |
+ |
|
474 |
+ # Assert that build raises a warning here that is captured
|
|
475 |
+ # as plugin error, due to the fatal warning being set
|
|
476 |
+ result = cli.run(project=project, args=['build', 'target.bst'])
|
|
477 |
+ result.assert_main_error(ErrorDomain.STREAM, None)
|
|
478 |
+ result.assert_task_error(ErrorDomain.PLUGIN, CoreWarnings.REF_NOT_IN_TRACK)
|