Merge branch 'tristan/bst-1/misc-cleanup' into 'bst-1'

Backport some misc fixes (bst-1)

See merge request BuildStream/buildstream!1517
diff --git a/buildstream/__init__.py b/buildstream/__init__.py
index 895adc6..9bfa88a 100644
--- a/buildstream/__init__.py
+++ b/buildstream/__init__.py
@@ -28,6 +28,7 @@
 
     from .utils import UtilError, ProgramNotFoundError
     from .sandbox import Sandbox, SandboxFlags
+    from .types import Scope, Consistency, CoreWarnings
     from .plugin import Plugin
     from .source import Source, SourceError, Consistency, SourceFetcher
     from .element import Element, ElementError, Scope
diff --git a/buildstream/_artifactcache/artifactcache.py b/buildstream/_artifactcache/artifactcache.py
index 0beab55..48fd322 100644
--- a/buildstream/_artifactcache/artifactcache.py
+++ b/buildstream/_artifactcache/artifactcache.py
@@ -21,7 +21,7 @@
 import string
 from collections import Mapping, namedtuple
 
-from ..element import _KeyStrength
+from ..types import _KeyStrength
 from .._exceptions import ArtifactError, ImplError, LoadError, LoadErrorReason
 from .._message import Message, MessageType
 from .. import utils
diff --git a/buildstream/_loader/loader.py b/buildstream/_loader/loader.py
index 1605a82..b861e86 100644
--- a/buildstream/_loader/loader.py
+++ b/buildstream/_loader/loader.py
@@ -34,6 +34,7 @@
 from .loadelement import LoadElement
 from . import MetaElement
 from . import MetaSource
+from ..types import CoreWarnings
 
 
 # Loader():
diff --git a/buildstream/_project.py b/buildstream/_project.py
index 6e4f09c..6648998 100644
--- a/buildstream/_project.py
+++ b/buildstream/_project.py
@@ -31,7 +31,7 @@
 from ._artifactcache import ArtifactCache
 from ._elementfactory import ElementFactory
 from ._sourcefactory import SourceFactory
-from .plugin import CoreWarnings
+from .types import CoreWarnings
 from ._projectrefs import ProjectRefs, ProjectRefStorage
 from ._versions import BST_FORMAT_VERSION
 from ._loader import Loader
diff --git a/buildstream/element.py b/buildstream/element.py
index 0ef7f09..5f0e300 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -96,23 +96,8 @@
 from . import _signals
 from . import _site
 from ._platform import Platform
-from .plugin import CoreWarnings
 from .sandbox._config import SandboxConfig
-
-
-# _KeyStrength():
-#
-# Strength of cache key
-#
-class _KeyStrength(Enum):
-
-    # Includes strong cache keys of all build dependencies and their
-    # runtime dependencies.
-    STRONG = 1
-
-    # Includes names of direct build dependencies but does not include
-    # cache keys of dependencies.
-    WEAK = 2
+from .types import _KeyStrength, CoreWarnings
 
 
 class Scope(Enum):
diff --git a/buildstream/plugin.py b/buildstream/plugin.py
index 8fbac36..f278534 100644
--- a/buildstream/plugin.py
+++ b/buildstream/plugin.py
@@ -119,6 +119,7 @@
 from . import utils
 from ._exceptions import PluginError, ImplError
 from ._message import Message, MessageType
+from .types import CoreWarnings
 
 
 class Plugin():
@@ -817,25 +818,8 @@
             return self.name
 
 
-class CoreWarnings():
-    """CoreWarnings()
-
-    Some common warnings which are raised by core functionalities within BuildStream are found in this class.
-    """
-
-    OVERLAPS = "overlaps"
-    """
-    This warning will be produced when buildstream detects an overlap on an element
-        which is not whitelisted. See :ref:`Overlap Whitelist <public_overlap_whitelist>`
-    """
-
-    REF_NOT_IN_TRACK = "ref-not-in-track"
-    """
-    This warning will be produced when a source is configured with a reference
-    which is found to be invalid based on the configured track
-    """
-
-
+# A local table for _prefix_warning()
+#
 __CORE_WARNINGS = [
     value
     for name, value in CoreWarnings.__dict__.items()
diff --git a/buildstream/plugins/sources/git.py b/buildstream/plugins/sources/git.py
index a44717a..4952464 100644
--- a/buildstream/plugins/sources/git.py
+++ b/buildstream/plugins/sources/git.py
@@ -76,7 +76,7 @@
 
 **Configurable Warnings:**
 
-This plugin provides the following configurable warnings:
+This plugin provides the following :ref:`configurable warnings <configurable_warnings>`:
 
 - ``git:inconsistent-submodule`` - A submodule present in the git repository's .gitmodules was never
   added with `git submodule add`.
@@ -95,9 +95,10 @@
 
      The ``git:invalid-submodule`` warning is available since :ref:`format version 20 <project_format_version>`
 
-This plugin also utilises the following configurable core plugin warnings:
+This plugin also utilises the following configurable :class:`core warnings <buildstream.types.CoreWarnings>`:
 
-- 'ref-not-in-track' - The provided ref was not found in the provided track in the element's git repository.
+- :attr:`ref-not-in-track <buildstream.types.CoreWarnings.REF_NOT_IN_TRACK>` - The provided ref was not
+  found in the provided track in the element's git repository.
 """
 
 import os
@@ -108,9 +109,8 @@
 
 from configparser import RawConfigParser
 
-from buildstream import Source, SourceError, Consistency, SourceFetcher
+from buildstream import Source, SourceError, Consistency, SourceFetcher, CoreWarnings
 from buildstream import utils
-from buildstream.plugin import CoreWarnings
 
 GIT_MODULES = '.gitmodules'
 
diff --git a/buildstream/source.py b/buildstream/source.py
index 24e5b6c..7a705b4 100644
--- a/buildstream/source.py
+++ b/buildstream/source.py
@@ -404,7 +404,8 @@
 
         If the backend in question supports resolving references from
         a symbolic tracking branch or tag, then this should be implemented
-        to perform this task on behalf of ``build-stream track`` commands.
+        to perform this task on behalf of :ref:`bst track <invoking_track>`
+        commands.
 
         This usually requires fetching new content from a remote origin
         to see if a new ref has appeared for your branch or tag. If the
diff --git a/buildstream/types.py b/buildstream/types.py
index d54bf0b..f528aca 100644
--- a/buildstream/types.py
+++ b/buildstream/types.py
@@ -113,6 +113,31 @@
     """
 
 
+class CoreWarnings():
+    """CoreWarnings()
+
+    Some common warnings which are raised by core functionalities within BuildStream are found in this class.
+    """
+
+    OVERLAPS = "overlaps"
+    """
+    This warning will be produced when buildstream detects an overlap on an element
+        which is not whitelisted. See :ref:`Overlap Whitelist <public_overlap_whitelist>`
+    """
+
+    REF_NOT_IN_TRACK = "ref-not-in-track"
+    """
+    This warning will be produced when a source is configured with a reference
+    which is found to be invalid based on the configured track
+    """
+
+    BAD_ELEMENT_SUFFIX = "bad-element-suffix"
+    """
+    This warning will be produced when an element whose name does not end in .bst
+    is referenced either on the command line or by another element
+    """
+
+
 # _KeyStrength():
 #
 # Strength of cache key
diff --git a/doc/source/format_project.rst b/doc/source/format_project.rst
index 1d55bd7..3462a4d 100644
--- a/doc/source/format_project.rst
+++ b/doc/source/format_project.rst
@@ -143,7 +143,7 @@
   - ref-not-in-track
   - <plugin>:<warning>
 
-BuildStream provides a collection of :class:`Core Warnings <buildstream.plugin.CoreWarnings>` which may be raised
+BuildStream provides a collection of :class:`Core Warnings <buildstream.types.CoreWarnings>` which may be raised
 by a variety of plugins. Other configurable warnings are plugin specific and should be noted within their individual documentation.
 
 .. note::
diff --git a/tests/sources/git.py b/tests/sources/git.py
index 9b59e30..3a6d662 100644
--- a/tests/sources/git.py
+++ b/tests/sources/git.py
@@ -414,9 +414,18 @@
 
 @pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")
 @pytest.mark.datafiles(os.path.join(DATA_DIR, 'template'))
-def test_ref_not_in_track_warn(cli, tmpdir, datafiles):
+@pytest.mark.parametrize("fail", ['warn', 'error'])
+def test_ref_not_in_track(cli, tmpdir, datafiles, fail):
     project = os.path.join(datafiles.dirname, datafiles.basename)
 
+    # Make the warning an error if we're testing errors
+    if fail == 'error':
+        project_template = {
+            "name": "foo",
+            "fatal-warnings": [CoreWarnings.REF_NOT_IN_TRACK]
+        }
+        _yaml.dump(project_template, os.path.join(project, 'project.conf'))
+
     # Create the repo from 'repofiles', create a branch without latest commit
     repo = create_repo('git', str(tmpdir))
     ref = repo.create(os.path.join(project, 'repofiles'))
@@ -435,48 +444,15 @@
     }
     _yaml.dump(element, os.path.join(project, 'target.bst'))
 
-    # Assert the warning is raised as ref is not in branch foo.
-    # Assert warning not error to the user, when not set as fatal.
     result = cli.run(project=project, args=['build', 'target.bst'])
-    assert "The ref provided for the element does not exist locally" in result.stderr
 
-
-@pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")
-@pytest.mark.datafiles(os.path.join(DATA_DIR, 'template'))
-def test_ref_not_in_track_warn_error(cli, tmpdir, datafiles):
-    project = os.path.join(datafiles.dirname, datafiles.basename)
-
-    # Add fatal-warnings ref-not-in-track to project.conf
-    project_template = {
-        "name": "foo",
-        "fatal-warnings": [CoreWarnings.REF_NOT_IN_TRACK]
-    }
-
-    _yaml.dump(project_template, os.path.join(project, 'project.conf'))
-
-    # Create the repo from 'repofiles', create a branch without latest commit
-    repo = create_repo('git', str(tmpdir))
-    ref = repo.create(os.path.join(project, 'repofiles'))
-
-    gitsource = repo.source_config(ref=ref)
-
-    # Overwrite the track value to the added branch
-    gitsource['track'] = 'foo'
-
-    # Write out our test target
-    element = {
-        'kind': 'import',
-        'sources': [
-            gitsource
-        ]
-    }
-    _yaml.dump(element, os.path.join(project, 'target.bst'))
-
-    # Assert that build raises a warning here that is captured
-    # as plugin error, due to the fatal warning being set
-    result = cli.run(project=project, args=['build', 'target.bst'])
-    result.assert_main_error(ErrorDomain.STREAM, None)
-    result.assert_task_error(ErrorDomain.PLUGIN, CoreWarnings.REF_NOT_IN_TRACK)
+    # Assert a warning or an error depending on what we're checking
+    if fail == 'error':
+        result.assert_main_error(ErrorDomain.STREAM, None)
+        result.assert_task_error(ErrorDomain.PLUGIN, CoreWarnings.REF_NOT_IN_TRACK)
+    else:
+        result.assert_success()
+        assert "ref-not-in-track" in result.stderr
 
 
 @pytest.mark.skipif(HAVE_GIT is False, reason="git is not available")