Skip to content

Commit 554a546

Browse files
committed
allow installation of broken symlinks within folders
1 parent 9cfcccd commit 554a546

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

metomi/rose/checksum.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,16 @@ def get_checksum(name, checksum_func=None):
7070
for filename in filenames:
7171
filepath = os.path.join(path, filename)
7272
source = os.path.join(name, filepath)
73-
checksum = checksum_func(source, name)
74-
mode = os.stat(os.path.realpath(source)).st_mode
73+
74+
if os.path.islink(source) and not os.path.exists(source):
75+
# If the source is a broken link within a directory
76+
# install without failing (unlike a single file)
77+
checksum = os.path.realpath(source)
78+
mode = os.lstat(source).st_mode
79+
else:
80+
checksum = checksum_func(source, name)
81+
mode = os.stat(os.path.realpath(source)).st_mode
82+
7583
path_and_checksum_list.append((filepath, checksum, mode))
7684
return path_and_checksum_list
7785

metomi/rose/loc_handlers/rsync_remote_check.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ def main(path, str_blob, str_tree):
6262
if filename.startswith("."):
6363
continue
6464
name = os.path.join(dirpath, filename)
65+
# Bypass this check if rsyncing a broken symlink.
66+
if os.path.islink(name) and not os.path.exists(name):
67+
continue
6568
stat = os.stat(name)
6669
print(stat.st_mode, stat.st_mtime, stat.st_size, name)
6770
elif os.path.isfile(path):
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env bash
2+
#-------------------------------------------------------------------------------
3+
# Copyright (C) British Crown (Met Office) & Contributors.
4+
#
5+
# This file is part of Rose, a framework for meteorological suites.
6+
#
7+
# Rose is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# Rose is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with Rose. If not, see <http://www.gnu.org/licenses/>.
19+
#-------------------------------------------------------------------------------
20+
# Test "rose app-run", file installation will not fail if a broken
21+
# symlink is contained in a repository or directory.
22+
# See https://github.com/metomi/rose/issues/2946
23+
24+
. "$(dirname "$0")/test_header"
25+
26+
tests 4
27+
28+
test_init <<__CONFIG__
29+
[command]
30+
default=true
31+
32+
[file:destination]
33+
source=${HOSTNAME}:${TEST_DIR}/source
34+
__CONFIG__
35+
36+
# Create a broken symlink dir
37+
mkdir -p ${TEST_DIR}/source/
38+
touch ${TEST_DIR}/source/missing
39+
ln -s ${TEST_DIR}/source/missing ${TEST_DIR}/source/link
40+
rm ${TEST_DIR}/source/missing
41+
42+
test_setup
43+
44+
# It doesn't fail when rsync installs broken symlink dirs:
45+
run_pass "${TEST_KEY_BASE}-rsync" rose app-run --config=../config
46+
file_grep_fail "${TEST_KEY_BASE}-rsync.err" \
47+
"No such file" \
48+
"${TEST_KEY_BASE}-rsync.err"
49+
50+
# Turn the source file into a Git repo and try to use the git file-handler:
51+
git -C ${TEST_DIR}/source init
52+
git -C ${TEST_DIR}/source add .
53+
git -C ${TEST_DIR}/source commit -a -m "my_commit"
54+
sed -i 'sXsource=.*Xsource=git:../source::./::HEADX' ../config/rose-app.conf
55+
56+
# It doesn't fail when git installs broken symlink dirs:
57+
run_pass "${TEST_KEY_BASE}-git" rose app-run --config=../config
58+
file_grep_fail "${TEST_KEY_BASE}-git.err" \
59+
"No such file" \
60+
"${TEST_KEY_BASE}-git.err"

0 commit comments

Comments
 (0)