-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathdependency.functions
More file actions
256 lines (216 loc) · 8.03 KB
/
Copy pathdependency.functions
File metadata and controls
256 lines (216 loc) · 8.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# This file is part of shellfire core. It is subject to the licence terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/shellfire-dev/core/master/COPYRIGHT. No part of shellfire core, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
# Copyright © 2014-2015 The developers of shellfire core. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/shellfire-dev/core/master/COPYRIGHT.
core_usesIn core functions path compatibility
core_usesIn core/dependency check languagePackageManagers
core_usesIn core/variable array
core_init_defines core_dependency_declares
core_init_defines core_dependency_declaresAsArray
core_init_defines core_dependency_requires
core_init_defines core_dependency_fallback
core_init_defines core_dependency_oneOf
core_dependency_fallback !'*' lsb_release
core_dependency_determinePackageManager()
{
if core_variable_array_iterateAsCallbacksShortcut _core_dependency_check_functions; then
return 0
fi
# Alternatively, we can use /etc/debian_version's presence in a check above
# Or parse /etc/lsb-release for DISTRIB_ID
if core_compatibility_whichNoOutput lsb_release; then
local lsbDistributor="$(lsb_release --id --short)"
if [ -n "$lsbDistributor" ]; then
core_dependency_packageManager="$lsbDistributor"
return 0
fi
fi
core_dependency_packageManager='Unknown'
}
core_functions_register _core_dependency_functions core_dependency_determinePackageManager
_core_dependency_addToPackagesToInstallIfRequired()
{
if core_variable_array_contains packagesToInstall "$pathPackage"; then
return 0
fi
core_variable_array_append packagesToInstall "$pathPackage"
}
_core_dependency_addToReplacementPathIfRequired()
{
local filePath="$1"
local folderPath="$(core_compatibility_dirname "$filePath")"
if [ -z "$folderPath" ]; then
return 0
fi
local replacementPathFragment
local IFS=':'
for replacementPathFragment in $replacementPath
do
if [ "$replacementPathFragment" = "$folderPath" ]; then
return 0
fi
done
replacementPath="$folderPath:$replacementPath"
}
_core_dependency_addFromInternalDataSource()
{
local internalDataSourceName="_core_dependency_internalDataSource_${packageManager}"
if core_variable_isUnset "$internalDataSourceName"; then
foundInternally=0
return 0
fi
local core_variable_indirectValue_result
core_variable_indirectValue "$internalDataSourceName"
while IFS=' ' read -r pathProgramName pathPackage pathAbsoluteFilePath
do
if [ "$programName" = "$pathProgramName" ]; then
foundInternally=1
# We use an existence check. This allows for more complex installatons, eg brew-rmtree, which don't install binaries
if [ ! -e "$pathAbsoluteFilePath" ]; then
_core_dependency_addToPackagesToInstallIfRequired
fi
_core_dependency_addToReplacementPathIfRequired "$pathAbsoluteFilePath"
return 0
fi
:
done <<-EOF
$core_variable_indirectValue_result
EOF
foundInternally=0
return 0
}
_core_dependency_addFromExternalDataSources()
{
local externalDataSourceFolderPath
local externalDataSourceFilePath
if core_variable_isSet HOME; then
set -- \
"$HOME"/."$_program_name" \
"$HOME"/."$core_libraryName" \
"$_program_etcPath"/"$_program_name" \
"$_program_etcPath"/"$core_libraryName"
else
set -- \
"$_program_etcPath"/"$_program_name" \
"$_program_etcPath"/"$core_libraryName"
fi
# First encountered path wins
for externalDataSourceFolderPath in "$@"
do
externalDataSourceFilePath="$externalDataSourceFolderPath"/paths.d/"$packageManager"/"$programName".path
if ! core_path_isReadableNonEmptyFilePath "$externalDataSourceFilePath"; then
continue
fi
IFS=' ' read -r pathProgramName pathPackage pathAbsoluteFilePath <"$externalDataSourceFilePath"
# We use an existence check. This allows for more complex installatons, eg brew-rmtree, which don't install binaries
if [ ! -e "$pathAbsoluteFilePath" ]; then
_core_dependency_addToPackagesToInstallIfRequired
fi
_core_dependency_addToReplacementPathIfRequired "$pathAbsoluteFilePath"
foundInternally=1
return
done
}
core_dependency_add()
{
local pathProgramName
local pathPackage
local pathAbsoluteFilePath
local foundInternally=0
_core_dependency_addFromInternalDataSource
if [ $foundInternally -eq 0 ]; then
_core_dependency_addFromExternalDataSources
fi
if [ $foundInternally -eq 0 ]; then
if [ "$packageManager" != 'Unknown' ]; then
core_message INFO "Dependency '$programName' for packageManager '$packageManager' not in any known .path file (or internally)"
fi
return 0
fi
if [ "$(core_compatibility_basename "$pathAbsoluteFilePath")" = "$programName" ]; then
return 0
fi
# Make a temporary folder to contain a symlink to this program so names work correctly; add to the path
if [ -z "$temporaryPathForWeirdlyLinkedFiles" ]; then
local TMP_FOLDER
core_temporaryFiles_newFolderToRemoveOnExit
temporaryPathForWeirdlyLinkedFiles="$TMP_FOLDER"
replacementPath="$temporaryPathForWeirdlyLinkedFiles:$replacementPath"
fi
ln -s "$pathAbsoluteFilePath" "$temporaryPathForWeirdlyLinkedFiles"/"$programName"
}
# Special bash-ism
command_not_found_handle()
{
local programNotFound="$1"
shift 1
core_exitError $core_commandLine_exitCode_OSFILE "command_not_found_handle:Essential dependency '$programNotFound' not found on the PATH (with arguments '$@')"
}
core_dependency_setUpPathAndInstallMissing()
{
# A standard path, excluding games, but including any sibling binaries to our one
# Adjusted for the weirdness that is NetBSD
local replacementPath
if core_compatibility_whichNoOutput uname; then
local operatingSystem="$(uname)"
else
local operatingSystem=''
fi
if [ "$operatingSystem" = 'NetBSD' ]; then
replacementPath='/usr/pkg/gnu/sbin:/usr/pkg/gnu/bin:/usr/pkg/sbin:/usr/pkg/bin:/usr/sbin:/usr/bin:/sbin:/bin'
else
replacementPath='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
fi
_core_dependency_addToReplacementPathIfRequired "$core_init_ourSymlinkPath"
_core_dependency_addToReplacementPathIfRequired "$core_init_ourPath"
local alreadyHandledProgramNames
local alreadyHandledProgramNames_initialised
core_variable_array_initialise alreadyHandledProgramNames
local packagesToInstall
local packagesToInstall_initialised
core_variable_array_initialise packagesToInstall
local temporaryPathForWeirdlyLinkedFiles=''
local packageManager
local programName
local alreadyInstalledProgramName
local originalIFS="$IFS"
local IFS=' '
while IFS=' ' read -r packageManager programName
do
IFS="$originalIFS"
case "$packageManager" in
'*'|"$core_dependency_packageManager")
packageManager="$core_dependency_packageManager"
if core_variable_array_contains alreadyHandledProgramNames "$programName"; then
continue
fi
core_variable_array_append alreadyHandledProgramNames "$programName"
core_dependency_add
;;
# Because of the heredoc, there's an extra blank line. A messy alternative is https://unix.stackexchange.com/questions/102891/posix-compliant-way-to-work-with-a-list-of-filenames-possibly-with-whitespace
'')
break
;;
*)
continue
;;
esac
done <<-EOF
${_core_dependency_requires}
EOF
IFS="$originalIFS"
if ! core_variable_array_isEmpty packagesToInstall; then
core_message NOTICE "Installing missing packages '$(core_variable_array_string packagesToInstall " ")'"
core_variable_array_passToFunctionAsArguments packagesToInstall core_dependency_check_${core_dependency_packageManager}_packageManager
fi
# In bash, this cleans the 'hash' of paths (see hash builtin, hash -r)
export PATH="$replacementPath"
}
core_functions_register _core_dependency_functions core_dependency_setUpPathAndInstallMissing
core_dependency_installDependencies()
{
if core_variable_isUnset _program_ignoreDependencies; then
_program_ignoreDependencies=no
fi
if core_variable_isFalse "$_program_ignoreDependencies"; then
core_functions_execute _core_dependency_functions "$@"
fi
}