You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildstream.apache.org by gi...@apache.org on 2020/12/29 13:18:00 UTC
[buildstream] branch jennis/introduce_artifact_delete created (now
5c12d11)
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a change to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git.
at 5c12d11 docs: Add bst artifact delete to using_commands.rst
This branch includes the following new commits:
new 2d46569 _artifactcache.py: Add optional defer_prune flag to remove()
new 1878169 _artifactcache.py: Add prune() method
new e8573a6 _artifactelement.py: Add _get_cache_key() override
new 404fa91 cli.py: Add artifact delete command
new e53cfa1 cascache.py: Ensure path exists before trying to update the mtime
new c8d019f NEWS: Add news entry for bst artifact delete
new 04f7523 Update man pages now that bst artifact delete exists
new 5c12d11 docs: Add bst artifact delete to using_commands.rst
The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[buildstream] 05/08: cascache.py: Ensure path exists before trying
to update the mtime
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit e53cfa19e1ed43a0ac9259819f4522f780361f59
Author: James Ennis <ja...@codethink.com>
AuthorDate: Fri Jan 11 11:14:34 2019 +0000
cascache.py: Ensure path exists before trying to update the mtime
If an artifact is pulled from the cache without its buildtree,
CASCache.prune() will fail when it tries to update the mtimes
of the build tree's object files.
A new integration test has been added to tests/integration/artifact.py
which reflects this.
---
buildstream/_cas/cascache.py | 16 ++++++++++------
tests/frontend/artifact.py | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/buildstream/_cas/cascache.py b/buildstream/_cas/cascache.py
index 802fc13..02030bb 100644
--- a/buildstream/_cas/cascache.py
+++ b/buildstream/_cas/cascache.py
@@ -791,16 +791,20 @@ class CASCache():
def _reachable_refs_dir(self, reachable, tree, update_mtime=False):
if tree.hash in reachable:
return
+ try:
+ if update_mtime:
+ os.utime(self.objpath(tree))
- if update_mtime:
- os.utime(self.objpath(tree))
+ reachable.add(tree.hash)
- reachable.add(tree.hash)
+ directory = remote_execution_pb2.Directory()
- directory = remote_execution_pb2.Directory()
+ with open(self.objpath(tree), 'rb') as f:
+ directory.ParseFromString(f.read())
- with open(self.objpath(tree), 'rb') as f:
- directory.ParseFromString(f.read())
+ except FileNotFoundError:
+ # Just exit early if the file doesn't exist
+ return
for filenode in directory.files:
if update_mtime:
diff --git a/tests/frontend/artifact.py b/tests/frontend/artifact.py
index 3c3203d..b6f8fb9 100644
--- a/tests/frontend/artifact.py
+++ b/tests/frontend/artifact.py
@@ -166,3 +166,41 @@ def test_artifact_delete_unbuilt_artifact(cli, tmpdir, datafiles):
artifact = os.path.join('test', os.path.splitext(element)[0], cache_key)
expected_err = "WARNING Could not find ref '{}'".format(artifact)
assert expected_err in result.stderr
+
+
+# Test that an artifact pulled from it's remote cache (without it's buildtree) will not
+# throw an Exception when trying to prune the cache.
+@pytest.mark.datafiles(DATA_DIR)
+def test_artifact_delete_pulled_artifact_without_buildtree(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element = 'target.bst'
+
+ # Set up remote and local shares
+ local_cache = os.path.join(str(tmpdir), 'artifacts')
+ with create_artifact_share(os.path.join(str(tmpdir), 'remote')) as remote:
+ cli.configure({
+ 'artifacts': {'url': remote.repo, 'push': True},
+ 'cachedir': local_cache,
+ })
+
+ # Build the element
+ result = cli.run(project=project, args=['build', element])
+ result.assert_success()
+
+ # Make sure it's in the share
+ cache_key = cli.get_element_key(project, element)
+ assert remote.has_artifact('test', element, cache_key)
+
+ # Delete and then pull the artifact (without its buildtree)
+ result = cli.run(project=project, args=['artifact', 'delete', element])
+ result.assert_success()
+ assert cli.get_element_state(project, element) != 'cached'
+ result = cli.run(project=project, args=['artifact', 'pull', element])
+ result.assert_success()
+ assert cli.get_element_state(project, element) == 'cached'
+
+ # Now delete it again (it should have been pulled without the buildtree, but
+ # a digest of the buildtree is pointed to in the artifact's metadata
+ result = cli.run(project=project, args=['artifact', 'delete', element])
+ result.assert_success()
+ assert cli.get_element_state(project, element) != 'cached'
[buildstream] 04/08: cli.py: Add artifact delete command
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 404fa91a7e0af026a7a2aeb2bd4ac2d2dc100f23
Author: James Ennis <ja...@codethink.co.uk>
AuthorDate: Tue Mar 5 16:02:19 2019 +0000
cli.py: Add artifact delete command
This command provides a --no-prune option because or a large cache, pruning
can be an expensive operation. If a developer wishes to quicky rebuild an artifact,
they may consider using this option.
---
buildstream/_frontend/cli.py | 14 ++++++
buildstream/_stream.py | 42 ++++++++++++++++-
tests/frontend/artifact.py | 104 ++++++++++++++++++++++++++++++++++++++++++
tests/frontend/completions.py | 1 +
4 files changed, 160 insertions(+), 1 deletion(-)
diff --git a/buildstream/_frontend/cli.py b/buildstream/_frontend/cli.py
index 02ca52e..d8c46ce 100644
--- a/buildstream/_frontend/cli.py
+++ b/buildstream/_frontend/cli.py
@@ -1106,6 +1106,20 @@ def artifact_log(app, artifacts):
click.echo_via_pager(data)
+###################################################################
+# Artifact Delete Command #
+###################################################################
+@artifact.command(name='delete', short_help="Remove artifacts from the local cache")
+@click.option('--no-prune', 'no_prune', default=False, is_flag=True,
+ help="Do not prune the local cache of unreachable refs")
+@click.argument('artifacts', type=click.Path(), nargs=-1)
+@click.pass_obj
+def artifact_delete(app, artifacts, no_prune):
+ """Remove artifacts from the local cache"""
+ with app.initialized():
+ app.stream.artifact_delete(artifacts, no_prune)
+
+
##################################################################
# DEPRECATED Commands #
##################################################################
diff --git a/buildstream/_stream.py b/buildstream/_stream.py
index b0fce38..5c88042 100644
--- a/buildstream/_stream.py
+++ b/buildstream/_stream.py
@@ -30,11 +30,12 @@ from contextlib import contextmanager, suppress
from fnmatch import fnmatch
from ._artifactelement import verify_artifact_ref
-from ._exceptions import StreamError, ImplError, BstError, ArtifactElementError, set_last_task_error
+from ._exceptions import StreamError, ImplError, BstError, ArtifactElementError, CASCacheError, set_last_task_error
from ._message import Message, MessageType
from ._scheduler import Scheduler, SchedStatus, TrackQueue, FetchQueue, BuildQueue, PullQueue, PushQueue
from ._pipeline import Pipeline, PipelineSelection
from ._profile import Topics, profile_start, profile_end
+from .types import _KeyStrength
from . import utils, _yaml, _site
from . import Scope, Consistency
@@ -520,6 +521,45 @@ class Stream():
return logsdirs
+ # artifact_delete()
+ #
+ # Remove artifacts from the local cache
+ #
+ # Args:
+ # targets (str): Targets to remove
+ # no_prune (bool): Whether to prune the unreachable refs, default False
+ #
+ def artifact_delete(self, targets, no_prune):
+ # Return list of Element and/or ArtifactElement objects
+ target_objects = self.load_selection(targets, selection=PipelineSelection.NONE, load_refs=True)
+
+ # Some of the targets may refer to the same key, so first obtain a
+ # set of the refs to be removed.
+ remove_refs = set()
+ for obj in target_objects:
+ for key_strength in [_KeyStrength.STRONG, _KeyStrength.WEAK]:
+ key = obj._get_cache_key(strength=key_strength)
+ remove_refs.add(obj.get_artifact_name(key=key))
+
+ ref_removed = False
+ for ref in remove_refs:
+ try:
+ self._artifacts.remove(ref, defer_prune=True)
+ except CASCacheError as e:
+ self._message(MessageType.WARN, "{}".format(e))
+ continue
+
+ self._message(MessageType.INFO, "Removed: {}".format(ref))
+ ref_removed = True
+
+ # Prune the artifact cache
+ if ref_removed and not no_prune:
+ with self._context.timed_activity("Pruning artifact cache"):
+ self._artifacts.prune()
+
+ if not ref_removed:
+ self._message(MessageType.INFO, "No artifacts were removed")
+
# source_checkout()
#
# Checkout sources of the target element to the specified location
diff --git a/tests/frontend/artifact.py b/tests/frontend/artifact.py
index c8301c5..3c3203d 100644
--- a/tests/frontend/artifact.py
+++ b/tests/frontend/artifact.py
@@ -22,6 +22,7 @@ import os
import pytest
from buildstream.plugintestutils import cli
+from tests.testutils import create_artifact_share
# Project directory
@@ -62,3 +63,106 @@ def test_artifact_log(cli, datafiles):
assert result.exit_code == 0
# The artifact is cached under both a strong key and a weak key
assert (log + log) == result.output
+
+
+# Test that we can delete the artifact of the element which corresponds
+# to the current project state
+@pytest.mark.datafiles(DATA_DIR)
+def test_artifact_delete_element(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element = 'target.bst'
+
+ # Build the element and ensure it's cached
+ result = cli.run(project=project, args=['build', element])
+ result.assert_success()
+ assert cli.get_element_state(project, element) == 'cached'
+
+ result = cli.run(project=project, args=['artifact', 'delete', element])
+ result.assert_success()
+ assert cli.get_element_state(project, element) != 'cached'
+
+
+# Test that we can delete an artifact by specifying its ref.
+@pytest.mark.datafiles(DATA_DIR)
+def test_artifact_delete_artifact(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element = 'target.bst'
+
+ # Configure a local cache
+ local_cache = os.path.join(str(tmpdir), 'artifacts')
+ cli.configure({'cachedir': local_cache})
+
+ # First build an element so that we can find its artifact
+ result = cli.run(project=project, args=['build', element])
+ result.assert_success()
+
+ # Obtain the artifact ref
+ cache_key = cli.get_element_key(project, element)
+ artifact = os.path.join('test', os.path.splitext(element)[0], cache_key)
+
+ # Explicitly check that the ARTIFACT exists in the cache
+ assert os.path.exists(os.path.join(local_cache, 'cas', 'refs', 'heads', artifact))
+
+ # Delete the artifact
+ result = cli.run(project=project, args=['artifact', 'delete', artifact])
+ result.assert_success()
+
+ # Check that the ARTIFACT is no longer in the cache
+ assert not os.path.exists(os.path.join(local_cache, 'cas', 'refs', 'heads', artifact))
+
+
+# Test the `bst artifact delete` command with multiple, different arguments.
+@pytest.mark.datafiles(DATA_DIR)
+def test_artifact_delete_element_and_artifact(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element = 'target.bst'
+ dep = 'compose-all.bst'
+
+ # Configure a local cache
+ local_cache = os.path.join(str(tmpdir), 'artifacts')
+ cli.configure({'cachedir': local_cache})
+
+ # First build an element so that we can find its artifact
+ result = cli.run(project=project, args=['build', element])
+ result.assert_success()
+ assert cli.get_element_state(project, element) == 'cached'
+ assert cli.get_element_state(project, dep) == 'cached'
+
+ # Obtain the artifact ref
+ cache_key = cli.get_element_key(project, element)
+ artifact = os.path.join('test', os.path.splitext(element)[0], cache_key)
+
+ # Explicitly check that the ARTIFACT exists in the cache
+ assert os.path.exists(os.path.join(local_cache, 'cas', 'refs', 'heads', artifact))
+
+ # Delete the artifact
+ result = cli.run(project=project, args=['artifact', 'delete', artifact, dep])
+ result.assert_success()
+
+ # Check that the ARTIFACT is no longer in the cache
+ assert not os.path.exists(os.path.join(local_cache, 'cas', 'refs', 'heads', artifact))
+
+ # Check that the dependency ELEMENT is no longer cached
+ assert cli.get_element_state(project, dep) != 'cached'
+
+
+# Test that we receive the appropriate stderr when we try to delete an artifact
+# that is not present in the cache.
+@pytest.mark.datafiles(DATA_DIR)
+def test_artifact_delete_unbuilt_artifact(cli, tmpdir, datafiles):
+ project = os.path.join(datafiles.dirname, datafiles.basename)
+ element = 'target.bst'
+
+ # delete it, just in case it's there
+ _ = cli.run(project=project, args=['artifact', 'delete', element])
+
+ # Ensure the element is not cached
+ assert cli.get_element_state(project, element) != 'cached'
+
+ # Now try and remove it again (now we know its not there)
+ result = cli.run(project=project, args=['artifact', 'delete', element])
+
+ cache_key = cli.get_element_key(project, element)
+ artifact = os.path.join('test', os.path.splitext(element)[0], cache_key)
+ expected_err = "WARNING Could not find ref '{}'".format(artifact)
+ assert expected_err in result.stderr
diff --git a/tests/frontend/completions.py b/tests/frontend/completions.py
index 1f29fda..7810a06 100644
--- a/tests/frontend/completions.py
+++ b/tests/frontend/completions.py
@@ -57,6 +57,7 @@ SOURCE_COMMANDS = [
ARTIFACT_COMMANDS = [
'checkout ',
+ 'delete ',
'push ',
'pull ',
'log ',
[buildstream] 06/08: NEWS: Add news entry for bst artifact delete
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit c8d019fe08b384ca7a3e7bd85c1af9e9e96cd5af
Author: James Ennis <ja...@codethink.co.uk>
AuthorDate: Wed Mar 13 12:10:57 2019 +0000
NEWS: Add news entry for bst artifact delete
---
NEWS | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/NEWS b/NEWS
index 0ff7702..85bf27c 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@
buildstream 1.3.1
=================
+ o Added `bst artifact delete` subcommand. This command removes artifacts from
+ the local cache. Mulitple element names and artifact refs can be specified
+ as arguments.
+
o BREAKING CHANGE: The top level commands `checkout`, `push` and `pull` have
been moved to the `bst artifact` subcommand group and are now obsolete.
For example, you must now use `bst artifact pull hello.bst`.
[buildstream] 01/08: _artifactcache.py: Add optional defer_prune
flag to remove()
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 2d46569fd4948e65eb461cd43e8c8fdf090756ee
Author: James Ennis <ja...@codethink.co.uk>
AuthorDate: Tue Mar 5 15:55:39 2019 +0000
_artifactcache.py: Add optional defer_prune flag to remove()
---
buildstream/_artifactcache.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/buildstream/_artifactcache.py b/buildstream/_artifactcache.py
index 3303650..81b0e70 100644
--- a/buildstream/_artifactcache.py
+++ b/buildstream/_artifactcache.py
@@ -415,12 +415,14 @@ class ArtifactCache():
# Args:
# ref (artifact_name): The name of the artifact to remove (as
# generated by `Element.get_artifact_name`)
+ # defer_prune (bool): Optionally declare whether pruning should
+ # occur immediately after the ref is removed.
#
# Returns:
# (int): The amount of space recovered in the cache, in bytes
#
- def remove(self, ref):
- return self.cas.remove(ref)
+ def remove(self, ref, *, defer_prune=False):
+ return self.cas.remove(ref, defer_prune=defer_prune)
# get_artifact_directory():
#
[buildstream] 08/08: docs: Add bst artifact delete to
using_commands.rst
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 5c12d1180db7d6d289f2504a9d8d24f858e42fda
Author: James Ennis <ja...@codethink.co.uk>
AuthorDate: Wed Mar 13 12:14:12 2019 +0000
docs: Add bst artifact delete to using_commands.rst
---
doc/source/using_commands.rst | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/doc/source/using_commands.rst b/doc/source/using_commands.rst
index 312b907..53c3619 100644
--- a/doc/source/using_commands.rst
+++ b/doc/source/using_commands.rst
@@ -101,6 +101,13 @@ Artifact subcommands
.. click:: buildstream._frontend.cli:artifact_push
:prog: bst artifact push
+----
+
+.. _invoking_artifact_delete:
+
+.. click:: buildstream._frontend.cli:artifact_delete
+ :prog: bst artifact delete
+
Source subcommands
------------------
[buildstream] 02/08: _artifactcache.py: Add prune() method
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 1878169f940deac8b8fcacdaeee0284764c255d6
Author: James Ennis <ja...@codethink.co.uk>
AuthorDate: Wed Mar 13 12:31:29 2019 +0000
_artifactcache.py: Add prune() method
---
buildstream/_artifactcache.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/buildstream/_artifactcache.py b/buildstream/_artifactcache.py
index 81b0e70..7da2d95 100644
--- a/buildstream/_artifactcache.py
+++ b/buildstream/_artifactcache.py
@@ -424,6 +424,13 @@ class ArtifactCache():
def remove(self, ref, *, defer_prune=False):
return self.cas.remove(ref, defer_prune=defer_prune)
+ # prune():
+ #
+ # Prune the artifact cache of unreachable refs
+ #
+ def prune(self):
+ return self.cas.prune()
+
# get_artifact_directory():
#
# Get virtual directory for cached artifact of the specified Element.
[buildstream] 03/08: _artifactelement.py: Add _get_cache_key()
override
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit e8573a6ca3d02ba678a4d4acd2eee7851e6ac201
Author: James Ennis <ja...@codethink.co.uk>
AuthorDate: Tue Mar 5 16:01:01 2019 +0000
_artifactelement.py: Add _get_cache_key() override
---
buildstream/_artifactelement.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/buildstream/_artifactelement.py b/buildstream/_artifactelement.py
index a88e83a..a7915eb 100644
--- a/buildstream/_artifactelement.py
+++ b/buildstream/_artifactelement.py
@@ -59,6 +59,10 @@ class ArtifactElement(Element):
def _calculate_cache_key(self, dependencies=None):
return self._key
+ # Override Element._get_cache_key()
+ def _get_cache_key(self, strength=None):
+ return self._key
+
# verify_artifact_ref()
#
[buildstream] 07/08: Update man pages now that bst artifact delete
exists
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch jennis/introduce_artifact_delete
in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 04f75238603ace3dad94900c47b41ca453ad5160
Author: James Ennis <ja...@codethink.co.uk>
AuthorDate: Wed Mar 13 12:13:52 2019 +0000
Update man pages now that bst artifact delete exists
---
man/bst-artifact-checkout.1 | 2 +-
man/bst-artifact-delete.1 | 12 ++++++++++++
man/bst-artifact-log.1 | 2 +-
man/bst-artifact-pull.1 | 2 +-
man/bst-artifact-push.1 | 2 +-
man/bst-artifact-server.1 | 2 +-
man/bst-artifact.1 | 6 +++++-
man/bst-build.1 | 2 +-
man/bst-help.1 | 2 +-
man/bst-init.1 | 4 ++--
man/bst-shell.1 | 2 +-
man/bst-show.1 | 2 +-
man/bst-source-checkout.1 | 2 +-
man/bst-source-fetch.1 | 2 +-
man/bst-source-track.1 | 2 +-
man/bst-source.1 | 2 +-
man/bst-workspace-close.1 | 2 +-
man/bst-workspace-list.1 | 2 +-
man/bst-workspace-open.1 | 2 +-
man/bst-workspace-reset.1 | 2 +-
man/bst-workspace.1 | 2 +-
man/bst.1 | 5 ++++-
22 files changed, 41 insertions(+), 22 deletions(-)
diff --git a/man/bst-artifact-checkout.1 b/man/bst-artifact-checkout.1
index 2c11852..27b9954 100644
--- a/man/bst-artifact-checkout.1
+++ b/man/bst-artifact-checkout.1
@@ -1,4 +1,4 @@
-.TH "BST ARTIFACT CHECKOUT" "1" "12-Feb-2019" "" "bst artifact checkout Manual"
+.TH "BST ARTIFACT CHECKOUT" "1" "13-Mar-2019" "" "bst artifact checkout Manual"
.SH NAME
bst\-artifact\-checkout \- Checkout contents of an artifact
.SH SYNOPSIS
diff --git a/man/bst-artifact-delete.1 b/man/bst-artifact-delete.1
new file mode 100644
index 0000000..43ef9bb
--- /dev/null
+++ b/man/bst-artifact-delete.1
@@ -0,0 +1,12 @@
+.TH "BST ARTIFACT DELETE" "1" "13-Mar-2019" "" "bst artifact delete Manual"
+.SH NAME
+bst\-artifact\-delete \- Remove artifacts from the local cache
+.SH SYNOPSIS
+.B bst artifact delete
+[OPTIONS] [ARTIFACTS]...
+.SH DESCRIPTION
+Show logs of all artifacts
+.SH OPTIONS
+.TP
+\fB\-\-no\-prune\fP
+Do not prune the local cache of unreachable refs
diff --git a/man/bst-artifact-log.1 b/man/bst-artifact-log.1
index 6045e25..2be7702 100644
--- a/man/bst-artifact-log.1
+++ b/man/bst-artifact-log.1
@@ -1,4 +1,4 @@
-.TH "BST ARTIFACT LOG" "1" "12-Feb-2019" "" "bst artifact log Manual"
+.TH "BST ARTIFACT LOG" "1" "13-Mar-2019" "" "bst artifact log Manual"
.SH NAME
bst\-artifact\-log \- Show logs of an artifact
.SH SYNOPSIS
diff --git a/man/bst-artifact-pull.1 b/man/bst-artifact-pull.1
index b01b2bb..890090a 100644
--- a/man/bst-artifact-pull.1
+++ b/man/bst-artifact-pull.1
@@ -1,4 +1,4 @@
-.TH "BST ARTIFACT PULL" "1" "12-Feb-2019" "" "bst artifact pull Manual"
+.TH "BST ARTIFACT PULL" "1" "13-Mar-2019" "" "bst artifact pull Manual"
.SH NAME
bst\-artifact\-pull \- Pull a built artifact
.SH SYNOPSIS
diff --git a/man/bst-artifact-push.1 b/man/bst-artifact-push.1
index bc87c82..09b0684 100644
--- a/man/bst-artifact-push.1
+++ b/man/bst-artifact-push.1
@@ -1,4 +1,4 @@
-.TH "BST ARTIFACT PUSH" "1" "12-Feb-2019" "" "bst artifact push Manual"
+.TH "BST ARTIFACT PUSH" "1" "13-Mar-2019" "" "bst artifact push Manual"
.SH NAME
bst\-artifact\-push \- Push a built artifact
.SH SYNOPSIS
diff --git a/man/bst-artifact-server.1 b/man/bst-artifact-server.1
index f196b87..d5d9b8c 100644
--- a/man/bst-artifact-server.1
+++ b/man/bst-artifact-server.1
@@ -1,4 +1,4 @@
-.TH "BST-ARTIFACT-SERVER" "1" "12-Feb-2019" "" "bst-artifact-server Manual"
+.TH "BST-ARTIFACT-SERVER" "1" "13-Mar-2019" "" "bst-artifact-server Manual"
.SH NAME
bst-artifact-server \- CAS Artifact Server
.SH SYNOPSIS
diff --git a/man/bst-artifact.1 b/man/bst-artifact.1
index a4bbeb7..aa46e2e 100644
--- a/man/bst-artifact.1
+++ b/man/bst-artifact.1
@@ -1,4 +1,4 @@
-.TH "BST ARTIFACT" "1" "12-Feb-2019" "" "bst artifact Manual"
+.TH "BST ARTIFACT" "1" "13-Mar-2019" "" "bst artifact Manual"
.SH NAME
bst\-artifact \- Manipulate cached artifacts
.SH SYNOPSIS
@@ -23,3 +23,7 @@ Manipulate cached artifacts
\fBlog\fP
Show logs of an artifact
See \fBbst artifact-log(1)\fP for full documentation on the \fBlog\fP command.
+.PP
+\fBdelete\fP
+ Remove artifacts from the local cache
+ See \fBbst artifact-delete(1)\fP for full documentation on the \fBdelete\fP command.
diff --git a/man/bst-build.1 b/man/bst-build.1
index deee130..edb67a4 100644
--- a/man/bst-build.1
+++ b/man/bst-build.1
@@ -1,4 +1,4 @@
-.TH "BST BUILD" "1" "12-Feb-2019" "" "bst build Manual"
+.TH "BST BUILD" "1" "13-Mar-2019" "" "bst build Manual"
.SH NAME
bst\-build \- Build elements in a pipeline
.SH SYNOPSIS
diff --git a/man/bst-help.1 b/man/bst-help.1
index 35675db..feebf24 100644
--- a/man/bst-help.1
+++ b/man/bst-help.1
@@ -1,4 +1,4 @@
-.TH "BST HELP" "1" "12-Feb-2019" "" "bst help Manual"
+.TH "BST HELP" "1" "13-Mar-2019" "" "bst help Manual"
.SH NAME
bst\-help \- Print usage information
.SH SYNOPSIS
diff --git a/man/bst-init.1 b/man/bst-init.1
index 9b7b119..6f41d97 100644
--- a/man/bst-init.1
+++ b/man/bst-init.1
@@ -1,4 +1,4 @@
-.TH "BST INIT" "1" "12-Feb-2019" "" "bst init Manual"
+.TH "BST INIT" "1" "13-Mar-2019" "" "bst init Manual"
.SH NAME
bst\-init \- Initialize a new BuildStream project
.SH SYNOPSIS
@@ -18,7 +18,7 @@ interactive session.
The project name to use
.TP
\fB\-\-format\-version\fP INTEGER
-The required format version (default: 21)
+The required format version (default: 23)
.TP
\fB\-\-element\-path\fP PATH
The subdirectory to store elements in (default: elements)
diff --git a/man/bst-shell.1 b/man/bst-shell.1
index d223d0d..376cddb 100644
--- a/man/bst-shell.1
+++ b/man/bst-shell.1
@@ -1,4 +1,4 @@
-.TH "BST SHELL" "1" "12-Feb-2019" "" "bst shell Manual"
+.TH "BST SHELL" "1" "13-Mar-2019" "" "bst shell Manual"
.SH NAME
bst\-shell \- Shell into an element's sandbox environment
.SH SYNOPSIS
diff --git a/man/bst-show.1 b/man/bst-show.1
index 4fe0b71..54d02c3 100644
--- a/man/bst-show.1
+++ b/man/bst-show.1
@@ -1,4 +1,4 @@
-.TH "BST SHOW" "1" "12-Feb-2019" "" "bst show Manual"
+.TH "BST SHOW" "1" "13-Mar-2019" "" "bst show Manual"
.SH NAME
bst\-show \- Show elements in the pipeline
.SH SYNOPSIS
diff --git a/man/bst-source-checkout.1 b/man/bst-source-checkout.1
index f3101b6..aed31db 100644
--- a/man/bst-source-checkout.1
+++ b/man/bst-source-checkout.1
@@ -1,4 +1,4 @@
-.TH "BST SOURCE CHECKOUT" "1" "12-Feb-2019" "" "bst source checkout Manual"
+.TH "BST SOURCE CHECKOUT" "1" "13-Mar-2019" "" "bst source checkout Manual"
.SH NAME
bst\-source\-checkout \- Checkout sources for an element
.SH SYNOPSIS
diff --git a/man/bst-source-fetch.1 b/man/bst-source-fetch.1
index 0fb63a6..ddcd557 100644
--- a/man/bst-source-fetch.1
+++ b/man/bst-source-fetch.1
@@ -1,4 +1,4 @@
-.TH "BST SOURCE FETCH" "1" "12-Feb-2019" "" "bst source fetch Manual"
+.TH "BST SOURCE FETCH" "1" "13-Mar-2019" "" "bst source fetch Manual"
.SH NAME
bst\-source\-fetch \- Fetch sources in a pipeline
.SH SYNOPSIS
diff --git a/man/bst-source-track.1 b/man/bst-source-track.1
index 92f8cd3..9a24619 100644
--- a/man/bst-source-track.1
+++ b/man/bst-source-track.1
@@ -1,4 +1,4 @@
-.TH "BST SOURCE TRACK" "1" "12-Feb-2019" "" "bst source track Manual"
+.TH "BST SOURCE TRACK" "1" "13-Mar-2019" "" "bst source track Manual"
.SH NAME
bst\-source\-track \- Track new source references
.SH SYNOPSIS
diff --git a/man/bst-source.1 b/man/bst-source.1
index 8976425..4d396b3 100644
--- a/man/bst-source.1
+++ b/man/bst-source.1
@@ -1,4 +1,4 @@
-.TH "BST SOURCE" "1" "12-Feb-2019" "" "bst source Manual"
+.TH "BST SOURCE" "1" "13-Mar-2019" "" "bst source Manual"
.SH NAME
bst\-source \- Manipulate sources for an element
.SH SYNOPSIS
diff --git a/man/bst-workspace-close.1 b/man/bst-workspace-close.1
index 5c2659f..0b43cdf 100644
--- a/man/bst-workspace-close.1
+++ b/man/bst-workspace-close.1
@@ -1,4 +1,4 @@
-.TH "BST WORKSPACE CLOSE" "1" "12-Feb-2019" "" "bst workspace close Manual"
+.TH "BST WORKSPACE CLOSE" "1" "13-Mar-2019" "" "bst workspace close Manual"
.SH NAME
bst\-workspace\-close \- Close workspaces
.SH SYNOPSIS
diff --git a/man/bst-workspace-list.1 b/man/bst-workspace-list.1
index 6be37d6..f525267 100644
--- a/man/bst-workspace-list.1
+++ b/man/bst-workspace-list.1
@@ -1,4 +1,4 @@
-.TH "BST WORKSPACE LIST" "1" "12-Feb-2019" "" "bst workspace list Manual"
+.TH "BST WORKSPACE LIST" "1" "13-Mar-2019" "" "bst workspace list Manual"
.SH NAME
bst\-workspace\-list \- List open workspaces
.SH SYNOPSIS
diff --git a/man/bst-workspace-open.1 b/man/bst-workspace-open.1
index 4fd70fc..4a1065d 100644
--- a/man/bst-workspace-open.1
+++ b/man/bst-workspace-open.1
@@ -1,4 +1,4 @@
-.TH "BST WORKSPACE OPEN" "1" "12-Feb-2019" "" "bst workspace open Manual"
+.TH "BST WORKSPACE OPEN" "1" "13-Mar-2019" "" "bst workspace open Manual"
.SH NAME
bst\-workspace\-open \- Open a new workspace
.SH SYNOPSIS
diff --git a/man/bst-workspace-reset.1 b/man/bst-workspace-reset.1
index ad2fc70..d37a7f1 100644
--- a/man/bst-workspace-reset.1
+++ b/man/bst-workspace-reset.1
@@ -1,4 +1,4 @@
-.TH "BST WORKSPACE RESET" "1" "12-Feb-2019" "" "bst workspace reset Manual"
+.TH "BST WORKSPACE RESET" "1" "13-Mar-2019" "" "bst workspace reset Manual"
.SH NAME
bst\-workspace\-reset \- Reset a workspace to its original state
.SH SYNOPSIS
diff --git a/man/bst-workspace.1 b/man/bst-workspace.1
index b90505e..3376205 100644
--- a/man/bst-workspace.1
+++ b/man/bst-workspace.1
@@ -1,4 +1,4 @@
-.TH "BST WORKSPACE" "1" "12-Feb-2019" "" "bst workspace Manual"
+.TH "BST WORKSPACE" "1" "13-Mar-2019" "" "bst workspace Manual"
.SH NAME
bst\-workspace \- Manipulate developer workspaces
.SH SYNOPSIS
diff --git a/man/bst.1 b/man/bst.1
index b1f6e9f..ff5e79b 100644
--- a/man/bst.1
+++ b/man/bst.1
@@ -1,4 +1,4 @@
-.TH "BST" "1" "12-Feb-2019" "" "bst Manual"
+.TH "BST" "1" "13-Mar-2019" "" "bst Manual"
.SH NAME
bst \- Build and manipulate BuildStream projects...
.SH SYNOPSIS
@@ -67,6 +67,9 @@ The mirror to fetch from first, before attempting other mirrors
.TP
\fB\-\-pull\-buildtrees\fP
Include an element's build tree when pulling remote element artifacts
+.TP
+\fB\-\-cache\-buildtrees\fP [always|failure|never]
+Cache artifact build tree content on creation
.SH COMMANDS
.PP
\fBhelp\fP