A new plugin has been added for easier maintenance of the repository
mirrors. With
$ kas fetch-all-repositories kas-project.yml
all repositories used by kas-project.yml are cloned or updated in the
repository reference directory. The definition of the environmental variable
`KAS_REPO_REF_DIR` is mandatory.
Signed-off-by: Frank Bielig <
frank....@mbition.io>
Signed-off-by: Tobias Hunger <
tobias...@mbition.io>
---
CHANGELOG.md | 5 ++
docs/userguide.rst | 5 ++
kas-container | 3 +-
kas/plugins/__init__.py | 2 +
kas/plugins/fetch_all_repos.py | 91 ++++++++++++++++++++++++++++++++++
kas/repos.py | 3 ++
tests/test_commands.py | 50 ++++++++++++++-----
7 files changed, 145 insertions(+), 14 deletions(-)
create mode 100644 kas/plugins/fetch_all_repos.py
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 637c2fb..8b4c918 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
+2.5-mbition
+
+- kas: add support for fetch-all-repos
+
2.5
+
- kas: Apply patches before doing an environment setup
- kas: repos: strip dot from layer name
- kas: Introduce KAS_BUILD_DIR environment variable
diff --git a/docs/userguide.rst b/docs/userguide.rst
index e996245..9ddf3ca 100644
--- a/docs/userguide.rst
+++ b/docs/userguide.rst
@@ -86,6 +86,11 @@ typically provides a single command.
.. automodule:: kas.plugins.for_all_repos
+``fetch-all-repos`` plugin
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. automodule:: kas.plugins.fetch_all_repos
+
``shell`` plugin
~~~~~~~~~~~~~~~~
diff --git a/kas-container b/kas-container
index 787f65b..6d0a62a 100755
--- a/kas-container
+++ b/kas-container
@@ -31,6 +31,7 @@ usage()
{
printf "%b" "Usage: $0 [OPTIONS] { build | checkout | shell } [KASOPTIONS] KASFILE\n"
printf "%b" " $0 [OPTIONS] for-all-repos KASFILE COMMAND\n"
+ printf "%b" " $0 [OPTIONS] fetch-all-repos KASFILE\n"
printf "%b" " $0 [OPTIONS] clean\n"
printf "%b" "\nPositional arguments:\n"
printf "%b" "build\t\t\tCheck out repositories and build target.\n"
@@ -220,7 +221,7 @@ while [ $# -gt 0 ]; do
shift 1
break
;;
- build|checkout|for-all-repos)
+ build|checkout|for-all-repos|fetch-all-repos)
KAS_REPO_MOUNT_OPT_DEFAULT="ro"
KAS_CMD=$1
shift 1
diff --git a/kas/plugins/__init__.py b/kas/plugins/__init__.py
index bbdb072..936131b 100644
--- a/kas/plugins/__init__.py
+++ b/kas/plugins/__init__.py
@@ -40,12 +40,14 @@ def load():
"""
from . import build
from . import for_all_repos
+ from . import fetch_all_repos
from . import checkout
from . import shell
register_plugins(build)
register_plugins(checkout)
register_plugins(for_all_repos)
+ register_plugins(fetch_all_repos)
register_plugins(shell)
diff --git a/kas/plugins/fetch_all_repos.py b/kas/plugins/fetch_all_repos.py
new file mode 100644
index 0000000..84545da
--- /dev/null
+++ b/kas/plugins/fetch_all_repos.py
@@ -0,0 +1,91 @@
+# kas - setup tool for bitbake based projects
+#
+# Copyright (c) Frank Bielig, 2021
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+"""
+ This plugin implements the ``kas fetch-all-repos`` command.
+
+ When this command is executed, kas will fetch all repositories listed
+ in the chosen config file in the repository reference directory
+ defined by environment variable ``KAS_REPO_REF_DIR``.
+"""
+
+import os
+import pathlib
+import subprocess
+
+from kas.config import Config
+from kas.context import create_global_context
+from kas.libcmds import Macro
+
+__license__ = 'MIT'
+__copyright__ = 'Copyright (c) Frank Bielig, 2021'
+
+
+class FetchAllRepos:
+ name = 'fetch-all-repos'
+ helpmsg = (
+ 'Clone or update all referenced repositories.'
+ )
+
+ @classmethod
+ def setup_parser(cls, parser):
+ pass
+
+ def run(self, args):
+ ctx = create_global_context(args)
+ ctx.config = Config(args.config)
+
+ macro = Macro()
+ macro.add(FetchAllReposCommand())
+ macro.run(ctx, args.skip)
+
+
+class FetchAllReposCommand:
+ def __init__(self):
+ super().__init__()
+
+ def __str__(self):
+ return 'fetch-all-repos'
+
+ def execute(self, ctx):
+ if not ctx.kas_repo_ref_dir:
+ raise AssertionError("KAS_REPO_REF_DIR needs to be set")
+
+ ref_dir = pathlib.Path(ctx.kas_repo_ref_dir)
+
+ checked = set()
+ for repo in ctx.config.get_repos():
+ if repo.qualified_name in checked:
+ continue
+ if repo.is_local:
+ continue
+ repo_dir = os.path.join(ref_dir, repo.qualified_name)
+ if os.path.exists(repo_dir):
+ print("Updating %s ..." % repo.url)
+ subprocess.run(["git", "-C", repo_dir, "fetch"], check=True)
+ else:
+ print("Cloning %s ..." % repo.url)
+ subprocess.run(["git", "clone", "--bare", repo.url, repo_dir],
+ check=True)
+ checked.update({repo.qualified_name})
+
+
+__KAS_PLUGINS__ = [FetchAllRepos]
diff --git a/kas/repos.py b/kas/repos.py
index edd46ee..3e5f697 100644
--- a/kas/repos.py
+++ b/kas/repos.py
@@ -54,6 +54,9 @@ class Repo:
if item == 'layers':
return [os.path.join(self.path, layer).rstrip(os.sep + '.')
for layer in self._layers]
+ elif item == 'is_local':
+ url = urlparse(self.url)
+ return (url.netloc or 'file') == 'file'
elif item == 'qualified_name':
url = urlparse(self.url)
return ('{url.netloc}{url.path}'
diff --git a/tests/test_commands.py b/tests/test_commands.py
index 9762025..7b11e91 100644
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -23,30 +23,54 @@
import glob
import os
import shutil
+
+import pytest
+
from kas import kas
def test_for_all_repos(changedir, tmpdir):
- tdir = str(tmpdir.mkdir('test_commands'))
- shutil.rmtree(tdir, ignore_errors=True)
- shutil.copytree('tests/test_commands', tdir)
- os.chdir(tdir)
+ test_dir = str(tmpdir.mkdir('test_commands'))
+ shutil.rmtree(test_dir, ignore_errors=True)
+ shutil.copytree('tests/test_commands', test_dir)
+ os.chdir(test_dir)
kas.kas(['for-all-repos', 'test.yml',
- 'git rev-parse HEAD >> %s/ref_${KAS_REPO_NAME}' % (tdir)])
+ 'git rev-parse HEAD >> %s/ref_${KAS_REPO_NAME}' % test_dir])
with open('ref_kas_1.0', 'r') as f:
- assert(f.readline().strip()
- == '907816a5c4094b59a36aec12226e71c461c05b77')
+ assert (f.readline().strip()
+ == '907816a5c4094b59a36aec12226e71c461c05b77')
with open('ref_kas_1.1', 'r') as f:
- assert(f.readline().strip()
- == 'e9ca55a239caa1a2098e1d48773a29ea53c6cab2')
+ assert (f.readline().strip()
+ == 'e9ca55a239caa1a2098e1d48773a29ea53c6cab2')
+
+
+def test_fetch_all_repos(capsys, tmpdir):
+ test_dir = str(tmpdir.mkdir('test_commands'))
+ shutil.rmtree(test_dir, ignore_errors=True)
+ shutil.copytree('tests/test_commands', test_dir)
+
+ os.chdir(test_dir)
+ with pytest.raises(AssertionError):
+ kas.kas(['fetch-all-repos', 'test.yml'])
+
+ ref_dir = str(tmpdir.mkdir('repo_ref'))
+ os.environ['KAS_REPO_REF_DIR'] = ref_dir
+ kas.kas(['fetch-all-repos', 'test.yml'])
+ captured = capsys.readouterr()
+ assert(os.path.exists(os.path.join(ref_dir, 'github.com.siemens.kas.git')))
+ assert(captured.out.startswith("Cloning"))
+
+ kas.kas(['fetch-all-repos', 'test.yml'])
+ captured = capsys.readouterr()
+ assert(captured.out.startswith("Updating"))
def test_checkout(changedir, tmpdir):
- tdir = str(tmpdir.mkdir('test_commands'))
- shutil.rmtree(tdir, ignore_errors=True)
- shutil.copytree('tests/test_commands', tdir)
- os.chdir(tdir)
+ test_dir = str(tmpdir.mkdir('test_commands'))
+ shutil.rmtree(test_dir, ignore_errors=True)
+ shutil.copytree('tests/test_commands', test_dir)
+ os.chdir(test_dir)
kas.kas(['checkout', 'test.yml'])
# Ensure that local.conf and bblayers.conf are populated, check that no
--
2.31.1