Skip to content

Commit 3e1e981

Browse files
Improve auto-cache robustness
Enables fully offline work with auto-cache.: Skip remote fetches when the revision is already cached.
1 parent 76890ef commit 3e1e981

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

src/west/app/project.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,9 +1177,9 @@ def do_add_parser(self, parser_adder):
11771177
'--auto-cache',
11781178
help='''automatically setup local cache repositories
11791179
in a flat folder hierarchy, but with an additional
1180-
subfolder (hashed name) for different remote URLs.
1181-
Each local cache repository is automatically cloned
1182-
on first usage and synced on subsequent clones.
1180+
subfolder (hashed name) for different remote URLs. Each
1181+
local cache repository is automatically cloned on first
1182+
usage and synced on subsequent fetches (if necessary).
11831183
This cache has the lowest priority (Prio 2).''',
11841184
)
11851185

@@ -1203,7 +1203,8 @@ def do_add_parser(self, parser_adder):
12031203
workspace setup.
12041204
Only in case of auto-cache the 'west update' process updates the local
12051205
caches first, which then serve as the source for pulling changes into
1206-
the workspace.
1206+
the workspace. Thereby, the auto-cache only fetches updates from remote
1207+
if the specified revision is not already present in the local cache.
12071208
12081209
Example: Assume your manifest describes this workspace structure:
12091210
(workspace)
@@ -1233,7 +1234,8 @@ def do_add_parser(self, parser_adder):
12331234
folder hierarchy is setup automatically. Each repository is stored under a
12341235
directory named after the basename of its remote URL. To prevent conflicts
12351236
between repos with same name, a hash of the remote URL is used as subfolder.
1236-
Note: Each local cache repo is automatically synced on subsequent updates.
1237+
Note: Each local cache repo is automatically synced on subsequent updates on
1238+
demand (if the requested revision is not already contained within the cache).
12371239
(auto cache directory)
12381240
├── bar.git
12391241
│ ├── <hash>
@@ -1757,13 +1759,44 @@ def handle_auto_cache(self, project):
17571759
# Then clone the repository into the local cache.
17581760
cache_dir_parent = Path(cache_dir).parent
17591761
cache_dir_parent.mkdir(parents=True, exist_ok=True)
1762+
self.dbg(f'{project.name}: create auto-cache for {project.url} in {cache_dir}')
17601763
project.git(
17611764
['clone', '--mirror', '--', project.url, os.fspath(cache_dir)], cwd=cache_dir_parent
17621765
)
17631766
self.create_auto_cache_info(project, cache_dir)
17641767
else:
1765-
# The local cache already exists. Sync it with remote.
1766-
project.git(['remote', 'update', '--prune'], cwd=cache_dir)
1768+
# helper function to check if git commands in the auto-cache run successful
1769+
def check_git(cmd) -> bool:
1770+
'''
1771+
Helper function to run git command in the auto-cache directory
1772+
with suppressed output.
1773+
'''
1774+
p = project.git(
1775+
cmd, cwd=cache_dir, capture_stdout=True, capture_stderr=True, check=False
1776+
)
1777+
return not p.returncode
1778+
1779+
# Check if the revision is already contained in the auto-cache.
1780+
# True, if the command was successful (returncode 0), otherwise False.
1781+
contains_rev = not project.git(
1782+
['cat-file', '-e', f'{project.revision}^{{commit}}'],
1783+
cwd=cache_dir,
1784+
capture_stdout=True,
1785+
capture_stderr=True,
1786+
check=False,
1787+
).returncode
1788+
1789+
# return if the auto-cache already contains the requested revision
1790+
if contains_rev and self.fs != 'always':
1791+
self.dbg(
1792+
f'{project.name}: auto-cache remote update is skipped '
1793+
f'as it already contains revision {project.revision}'
1794+
)
1795+
return
1796+
1797+
# The auto-cache needs to be updated. Sync with remote.
1798+
self.dbg(f'{project.name}: update auto-cache ({cache_dir}) with remote')
1799+
project.git(['remote', 'update', '--prune'], cwd=cache_dir, check=False)
17671800

17681801
def init_project(self, project):
17691802
# update() helper. Initialize an uncloned project repository.

0 commit comments

Comments
 (0)