Skip to content

Commit 45bba5a

Browse files
committed
fix: Symlinking bin files now works
The algorithm for 'strict' and 'lenient' linking has a much cleaner implementation
1 parent 79be890 commit 45bba5a

File tree

4 files changed

+55
-109
lines changed

4 files changed

+55
-109
lines changed

pkg/lib/commands/do-global-install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ do-global-install() {
2222
done < "$BASALT_GLOBAL_DATA_DIR/global/dependencies"; unset dep
2323

2424
pkg.install_packages "$BASALT_GLOBAL_DATA_DIR/global" 'lenient' "${dependencies[@]}"
25-
pkg.phase_local_integration_recursive "$BASALT_GLOBAL_DATA_DIR/global" 'yes' 'strict' "${dependencies[@]}"
25+
pkg.phase_local_integration_recursive "$BASALT_GLOBAL_DATA_DIR/global" 'yes' 'lenient' "${dependencies[@]}"
2626
pkg.phase_local_integration_nonrecursive "$BASALT_GLOBAL_DATA_DIR/global"
2727
}

pkg/lib/util/pkg.sh

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ pkg.install_packages() {
2525
pkg.phase_extract_tarball "$package_id"
2626

2727
# Install transitive dependencies if they exist
28-
if [ -f "$BASALT_GLOBAL_DATA_DIR/store/packages/$package_id/basalt.toml" ]; then
29-
if util.get_toml_array "$BASALT_GLOBAL_DATA_DIR/store/packages/$package_id/basalt.toml" 'dependencies'; then
30-
pkg.install_packages "$BASALT_GLOBAL_DATA_DIR/store/packages/$package_id" 'strict' "${REPLIES[@]}"
28+
local package_dir="$BASALT_GLOBAL_DATA_DIR/store/packages/$package_id"
29+
if [ -f "$package_dir/basalt.toml" ]; then
30+
if util.get_toml_array "$package_dir/basalt.toml" 'dependencies'; then
31+
pkg.install_packages "$package_dir" 'strict' "${REPLIES[@]}"
3132
fi
3233
fi
3334

34-
# Only after all the dependencies are installed do we muck with the global packages
35+
# Only after all the transitive dependencies _for a particular direct dependency_ are installed do we
36+
# muck with the direct dependency itself
3537
pkg.phase_global_integration "$package_id"
3638
done; unset pkg
3739
}
@@ -147,7 +149,7 @@ pkg.phase_global_integration() {
147149
if [ -f "$project_dir/basalt.toml" ]; then
148150
# Install dependencies
149151
if util.get_toml_array "$project_dir/basalt.toml" 'dependencies'; then
150-
pkg.phase_local_integration_recursive "$project_dir" 'yes' 'strict' "${REPLIES[@]}"
152+
pkg.phase_local_integration_recursive "$project_dir" 'yes' 'lenient' "${REPLIES[@]}"
151153
pkg.phase_local_integration_nonrecursive "$project_dir"
152154
fi
153155
fi
@@ -167,6 +169,10 @@ pkg.phase_local_integration_recursive() {
167169
ensure.nonzero 'is_direct'
168170
ensure.nonzero 'symlink_mode'
169171

172+
if [[ "$symlink_mode" != @(strict|lenient) ]]; then
173+
util.die_unexpected_value 'symlink_mode'
174+
fi
175+
170176
local pkg=
171177
for pkg; do
172178
util.get_package_info "$pkg"
@@ -182,24 +188,10 @@ pkg.phase_local_integration_recursive() {
182188
# Perform symlinking
183189
if [ "$is_direct" = yes ]; then
184190
symlink.package "$original_package_dir/.basalt/packages" "$package_id"
185-
186-
if [ "$symlink_mode" = 'strict' ]; then
187-
symlink.bin_strict "$original_package_dir/.basalt/packages" "$package_id"
188-
elif [ "$symlink_mode" = 'lenient' ]; then
189-
symlink.bin_lenient "$original_package_dir/.basalt/packages" "$package_id"
190-
else
191-
util.die_unexpected_value 'symlink_mode'
192-
fi
191+
symlink.bin_"$symlink_mode" "$original_package_dir/.basalt/packages" "$package_id"
193192
elif [ "$is_direct" = no ]; then
194193
symlink.package "$original_package_dir/.basalt/transitive/packages" "$package_id"
195-
196-
if [ "$symlink_mode" = 'strict' ]; then
197-
symlink.bin_strict "$original_package_dir/.basalt/transitive/packages" "$package_id" "$package_id"
198-
elif [ "$symlink_mode" = 'lenient' ]; then
199-
symlink.bin_lenient "$original_package_dir/.basalt/transitive/packages" "$package_id" "$package_id"
200-
else
201-
util.die_unexpected_value 'symlink_mode'
202-
fi
194+
symlink.bin_"$symlink_mode" "$original_package_dir/.basalt/transitive/packages" "$package_id" "$package_id"
203195
else
204196
util.die_unexpected_value 'is_direct'
205197
fi

pkg/lib/util/print.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,11 @@ newindent.error() {
8585
printf "\033[0;31m%11s\033[0m %s\n" 'Error' "$1"
8686
fi
8787
}
88+
89+
newindent.warn() {
90+
if [ -n "${NO_COLOR+x}" ] || [ "$TERM" = dumb ]; then
91+
printf "%11s %s\n" 'Warn' "$1" >&2
92+
else
93+
printf "\033[0;33m%11s\033[0m %s\n" 'Warn' "$1" >&2
94+
fi
95+
}

pkg/lib/util/symlink.sh

Lines changed: 33 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,33 @@ symlink.package() {
2020
}
2121

2222
symlink.bin_strict() {
23+
unset REPLY; REPLY='no'
2324
local install_dir="$1" # e.g. "$BASALT_LOCAL_PROJECT_DIR/.basalt"
2425
local package_id="$2"
2526

2627
ensure.nonzero 'install_dir'
2728
ensure.nonzero 'package_id'
2829

29-
local package_dir="$BASALT_GLOBAL_DATA_DIR/store/packages/$site/$package@$version"
30+
local package_dir="$BASALT_GLOBAL_DATA_DIR/store/packages/$package_id"
3031
if [ -f "$package_dir/basalt.toml" ]; then
3132
if util.get_toml_array "$package_dir/basalt.toml" 'binDirs'; then
33+
REPLY='yes'
34+
3235
if ((${#REPLIES[@]} > 0)); then
3336
mkdir -p "$install_dir/bin"
3437
fi
3538

39+
local dir=
3640
for dir in "${REPLIES[@]}"; do
3741
if [ -d "$package_dir/$dir" ]; then
38-
for target in "$package_dir/$dir"/*; do
39-
local link_name="$install_dir/bin/${target##*/}"
40-
41-
if [ -e "$link_name" ]; then
42-
print-indent 'Warning' "Executable file '${target##*/} for package $package_id will clobber an identically-named file owned by a different package"
43-
fi
44-
45-
if ! ln -sf "$target" "$link_name"; then
46-
print.indent-die "Could not symlink file '${target##*/}' for package $site/$package@$version"
47-
fi
48-
done
42+
local file=
43+
for file in "$package_dir/$dir"/*; do
44+
symlink.bin_util_create_symlink "$install_dir" "$file"
45+
done; unset file
46+
else
47+
newindent.warn "Package '$package_id' improperly listed '$dir' as a directory in 'binDirs'"
4948
fi
50-
done
49+
done; unset dir
5150
fi
5251
fi
5352
}
@@ -59,102 +58,49 @@ symlink.bin_lenient() {
5958
ensure.nonzero 'install_dir'
6059
ensure.nonzero 'package_id'
6160

62-
local -a bins=()
63-
local remove_extensions='no'
64-
local package_dir="$BASALT_GLOBAL_DATA_DIR/store/packages/$package_id"
65-
if [ -f "$package_dir/basalt.toml" ]; then
66-
if util.get_toml_string "$package_dir/basalt.toml" 'binRemoveExtensions'; then
67-
if [ "$REPLY" = 'yes' ]; then
68-
remove_extensions='yes'
69-
fi
70-
fi
71-
72-
# TODO: cleanup?
73-
if util.get_toml_array "$package_dir/basalt.toml" 'binDirs'; then
74-
local dir=
75-
for dir in "${REPLIES[@]}"; do
76-
if [ -d "$package_dir/$dir" ]; then
77-
for file in "$package_dir/$dir"/*; do
78-
symlink.bin_lenient_util_create_symlink "$install_dir" "$file" "$remove_extensions"
79-
done
80-
fi
81-
done
82-
unset dir
83-
84-
return
85-
fi
86-
87-
symlink.bin_lenient_util_heuristics "$install_dir" "$package_id" "$remove_extensions"
88-
elif [ -f "$package_dir/package.sh" ]; then
89-
if util.extract_shell_variable "$package_dir/package.sh" 'REMOVE_EXTENSION'; then
90-
remove_extensions="$REPLY"
91-
fi
92-
93-
if util.extract_shell_variable "$package_dir/package.sh" 'BINS'; then
94-
IFS=':' read -ra bins <<< "$REPLY"
95-
96-
local file=
97-
for file in "${bins[@]}"; do
98-
if [ -d "$package_dir/$file" ]; then
99-
die "Specified directory '$file' in package.sh; only files are valid"
100-
elif [ ! -f "$package_dir/$file" ]; then
101-
log.warn "Executable file '$file' not found. Skipping"
102-
else
103-
symlink.bin_lenient_util_create_symlink "$install_dir" "$package_dir/$file" "$remove_extensions"
104-
fi
105-
done
106-
unset file
107-
else
108-
symlink.bin_lenient_util_heuristics "$install_dir" "$package_id" "$remove_extensions"
109-
fi
110-
else
111-
symlink.bin_lenient_util_heuristics "$install_dir" "$package_id" "$remove_extensions"
61+
symlink.bin_strict "$install_dir" "$package_id"
62+
if [ "$REPLY" = 'yes' ]; then
63+
return
11264
fi
113-
}
114-
115-
# @description Use heuristics to locate and symlink the bin files. This is ran when
116-
# the user does not supply any bin files/dirs with any config
117-
# @arg $1 package
118-
# @arg $2 Whether to remove extensions
119-
symlink.bin_lenient_util_heuristics() {
120-
local install_dir="$1"
121-
local package_id="$2"
122-
local remove_extensions="$3"
12365

66+
# USE HEURISTICS
12467
local package_dir="$BASALT_GLOBAL_DATA_DIR/store/packages/$package_id"
12568
if [ -d "$package_dir/bin" ]; then
69+
mkdir -p "$install_dir/bin" # TODO: do this only once
70+
local file=
12671
for file in "$package_dir"/bin/*; do
127-
symlink.bin_lenient_util_create_symlink "$install_dir" "$file" "$remove_extensions"
128-
done
72+
if [ -f "$file" ]; then
73+
symlink.bin_util_create_symlink "$install_dir" "$file"
74+
fi
75+
done; unset file
12976
elif [ -d "$package_dir/bins" ]; then
77+
mkdir -p "$install_dir/bin" # TODO: do this only once
78+
local file=
13079
for file in "$package_dir"/bins/*; do
131-
symlink.bin_lenient_util_create_symlink "$install_dir" "$file" "$remove_extensions"
132-
done
80+
if [ -f "$file" ]; then
81+
symlink.bin_util_create_symlink "$install_dir" "$file"
82+
fi
83+
done; unset file
13384
else
85+
mkdir -p "$install_dir/bin" # TODO: do this only once
86+
local file=
13487
for file in "$package_dir"/*; do
13588
if [ -f "$file" ] && [ -x "$file" ]; then
136-
symlink.bin_lenient_util_create_symlink "$install_dir" "$file" "$remove_extensions"
89+
symlink.bin_util_create_symlink "$install_dir" "$file"
13790
fi
138-
done
91+
done; unset file
13992
fi
14093
}
14194

14295
# @description Symlink the bin file to the correct location or
14396
# remove the symlink
14497
# @arg $1 The full path of the executable
14598
# @arg $2 Whether to remove extensions
146-
symlink.bin_lenient_util_create_symlink() {
99+
symlink.bin_util_create_symlink() {
147100
local install_dir="$1"
148101
local full_bin_file="$2"
149-
local remove_extensions="$3"
150102

151103
local bin_name="${full_bin_file##*/}"
152-
153-
if [[ "${remove_extensions:-no}" == @(yes|true) ]]; then
154-
bin_name="${bin_name%%.*}"
155-
fi
156-
157-
mkdir -p "$install_dir/bin" # TODO: do this only once
158104
if [ -L "$install_dir/bin/$bin_name" ]; then
159105
log.error "Skipping '$bin_name' since an existing symlink with the same name already exists"
160106
else

0 commit comments

Comments
 (0)