asdf

Форк
0
/
utils.bash 
898 строк · 24.9 Кб
1
# We shouldn't rely on the user's grep settings to be correct. If we set these
2
# here anytime asdf invokes grep it will be invoked with these options
3
# shellcheck disable=SC2034
4
GREP_OPTIONS="--color=never"
5
# shellcheck disable=SC2034
6
GREP_COLORS=
7

8
asdf_version() {
9
  local version git_rev
10
  version="v$(cat "$(asdf_dir)/version.txt")"
11
  if [ -d "$(asdf_dir)/.git" ]; then
12
    git_rev="$(git --git-dir "$(asdf_dir)/.git" rev-parse --short HEAD)"
13
    printf "%s-%s\n" "$version" "$git_rev"
14
  else
15
    printf "%s\n" "$version"
16
  fi
17
}
18

19
asdf_tool_versions_filename() {
20
  printf '%s\n' "${ASDF_DEFAULT_TOOL_VERSIONS_FILENAME:-.tool-versions}"
21
}
22

23
asdf_config_file() {
24
  printf '%s\n' "${ASDF_CONFIG_FILE:-$HOME/.asdfrc}"
25
}
26

27
asdf_data_dir() {
28
  local data_dir
29

30
  if [ -n "${ASDF_DATA_DIR}" ]; then
31
    data_dir="${ASDF_DATA_DIR}"
32
  elif [ -n "$HOME" ]; then
33
    data_dir="$HOME/.asdf"
34
  else
35
    data_dir=$(asdf_dir)
36
  fi
37

38
  printf "%s\n" "$data_dir"
39
}
40

41
asdf_dir() {
42
  if [ -z "$ASDF_DIR" ]; then
43
    local current_script_path=${BASH_SOURCE[0]}
44
    printf '%s\n' "$(
45
      cd -- "$(dirname "$(dirname "$current_script_path")")" || exit
46
      printf '%s\n' "$PWD"
47
    )"
48
  else
49
    printf '%s\n' "$ASDF_DIR"
50
  fi
51
}
52

53
asdf_plugin_repository_url() {
54
  printf "https://github.com/asdf-vm/asdf-plugins.git\n"
55
}
56

57
get_install_path() {
58
  local plugin=$1
59
  local install_type=$2
60
  local version=$3
61

62
  local install_dir
63
  install_dir="$(asdf_data_dir)/installs"
64

65
  [ -d "${install_dir}/${plugin}" ] || mkdir -p "${install_dir}/${plugin}"
66

67
  if [ "$install_type" = "version" ]; then
68
    printf "%s/%s/%s\n" "$install_dir" "$plugin" "$version"
69
  elif [ "$install_type" = "path" ]; then
70
    printf "%s\n" "$version"
71
  else
72
    printf "%s/%s/%s-%s\n" "$install_dir" "$plugin" "$install_type" "$version"
73
  fi
74
}
75

76
get_download_path() {
77
  local plugin=$1
78
  local install_type=$2
79
  local version=$3
80

81
  local download_dir
82
  download_dir="$(asdf_data_dir)/downloads"
83

84
  [ -d "${download_dir}/${plugin}" ] || mkdir -p "${download_dir}/${plugin}"
85

86
  if [ "$install_type" = "version" ]; then
87
    printf "%s/%s/%s\n" "$download_dir" "$plugin" "$version"
88
  elif [ "$install_type" = "path" ]; then
89
    return
90
  else
91
    printf "%s/%s/%s-%s\n" "$download_dir" "$plugin" "$install_type" "$version"
92
  fi
93
}
94

95
list_installed_versions() {
96
  local plugin_name=$1
97
  local plugin_path
98
  plugin_path=$(get_plugin_path "$plugin_name")
99

100
  local plugin_installs_path
101
  plugin_installs_path="$(asdf_data_dir)/installs/${plugin_name}"
102

103
  if [ -d "$plugin_installs_path" ]; then
104
    for install in "${plugin_installs_path}"/*/; do
105
      [[ -e "$install" ]] || break
106
      basename "$install" | sed 's/^ref-/ref:/'
107
    done
108
  fi
109
}
110

111
check_if_plugin_exists() {
112
  local plugin_name=$1
113

114
  # Check if we have a non-empty argument
115
  if [ -z "${1}" ]; then
116
    display_error "No plugin given"
117
    exit 1
118
  fi
119

120
  if [ ! -d "$(asdf_data_dir)/plugins/$plugin_name" ]; then
121
    display_error "No such plugin: $plugin_name"
122
    exit 1
123
  fi
124
}
125

126
check_if_version_exists() {
127
  local plugin_name=$1
128
  local version=$2
129

130
  check_if_plugin_exists "$plugin_name"
131

132
  local install_path
133
  install_path=$(find_install_path "$plugin_name" "$version")
134

135
  if [ "$version" != "system" ] && [ ! -d "$install_path" ]; then
136
    exit 1
137
  fi
138
}
139

140
version_not_installed_text() {
141
  local plugin_name=$1
142
  local version=$2
143

144
  printf "version %s is not installed for %s\n" "$version" "$plugin_name"
145
}
146

147
get_plugin_path() {
148
  if [ -n "$1" ]; then
149
    printf "%s\n" "$(asdf_data_dir)/plugins/$1"
150
  else
151
    printf "%s\n" "$(asdf_data_dir)/plugins"
152
  fi
153
}
154

155
display_error() {
156
  printf "%s\n" "$1" >&2
157
}
158

159
get_version_in_dir() {
160
  local plugin_name=$1
161
  local search_path=$2
162
  local legacy_filenames=$3
163

164
  local asdf_version
165

166
  file_name=$(asdf_tool_versions_filename)
167
  asdf_version=$(parse_asdf_version_file "$search_path/$file_name" "$plugin_name")
168

169
  if [ -n "$asdf_version" ]; then
170
    printf "%s\n" "$asdf_version|$search_path/$file_name"
171
    return 0
172
  fi
173

174
  for filename in $legacy_filenames; do
175
    local legacy_version
176
    legacy_version=$(parse_legacy_version_file "$search_path/$filename" "$plugin_name")
177

178
    if [ -n "$legacy_version" ]; then
179
      printf "%s\n" "$legacy_version|$search_path/$filename"
180
      return 0
181
    fi
182
  done
183
}
184

185
find_versions() {
186
  local plugin_name=$1
187
  local search_path=$2
188

189
  local version
190
  version=$(get_version_from_env "$plugin_name")
191
  if [ -n "$version" ]; then
192
    local upcase_name
193
    upcase_name=$(printf "%s\n" "$plugin_name" | tr '[:lower:]-' '[:upper:]_')
194
    local version_env_var="ASDF_${upcase_name}_VERSION"
195

196
    printf "%s\n" "$version|$version_env_var environment variable"
197
    return 0
198
  fi
199

200
  local plugin_path
201
  plugin_path=$(get_plugin_path "$plugin_name")
202
  local legacy_config
203
  legacy_config=$(get_asdf_config_value "legacy_version_file")
204
  local legacy_list_filenames_script
205
  legacy_list_filenames_script="${plugin_path}/bin/list-legacy-filenames"
206
  local legacy_filenames=""
207

208
  if [ "$legacy_config" = "yes" ] && [ -f "$legacy_list_filenames_script" ]; then
209
    legacy_filenames=$("$legacy_list_filenames_script")
210
  fi
211

212
  while [ "$search_path" != "/" ]; do
213
    version=$(get_version_in_dir "$plugin_name" "$search_path" "$legacy_filenames")
214
    if [ -n "$version" ]; then
215
      printf "%s\n" "$version"
216
      return 0
217
    fi
218
    search_path=$(dirname "$search_path")
219
  done
220

221
  get_version_in_dir "$plugin_name" "$HOME" "$legacy_filenames"
222

223
  if [ -f "$ASDF_DEFAULT_TOOL_VERSIONS_FILENAME" ]; then
224
    versions=$(parse_asdf_version_file "$ASDF_DEFAULT_TOOL_VERSIONS_FILENAME" "$plugin_name")
225
    if [ -n "$versions" ]; then
226
      printf "%s\n" "$versions|$ASDF_DEFAULT_TOOL_VERSIONS_FILENAME"
227
      return 0
228
    fi
229
  fi
230
}
231

232
display_no_version_set() {
233
  local plugin_name=$1
234
  printf "No version is set for %s; please run \`asdf <global | shell | local> %s <version>\`\n" "$plugin_name" "$plugin_name"
235
}
236

237
get_version_from_env() {
238
  local plugin_name=$1
239
  local upcase_name
240
  upcase_name=$(printf "%s\n" "$plugin_name" | tr '[:lower:]-' '[:upper:]_')
241
  local version_env_var="ASDF_${upcase_name}_VERSION"
242
  local version=${!version_env_var:-}
243
  printf "%s\n" "$version"
244
}
245

246
find_install_path() {
247
  local plugin_name=$1
248
  local version=$2
249

250
  # shellcheck disable=SC2162
251
  IFS=':' read -a version_info <<<"$version"
252

253
  if [ "$version" = "system" ]; then
254
    printf "\n"
255
  elif [ "${version_info[0]}" = "ref" ]; then
256
    local install_type="${version_info[0]}"
257
    local version="${version_info[1]}"
258
    get_install_path "$plugin_name" "$install_type" "$version"
259
  elif [ "${version_info[0]}" = "path" ]; then
260
    # This is for people who have the local source already compiled
261
    # Like those who work on the language, etc
262
    # We'll allow specifying path:/foo/bar/project in .tool-versions
263
    # And then use the binaries there
264
    local install_type="path"
265
    local version="path"
266

267
    util_resolve_user_path "${version_info[1]}"
268
    printf "%s\n" "${util_resolve_user_path_reply}"
269
  else
270
    local install_type="version"
271
    local version="${version_info[0]}"
272
    get_install_path "$plugin_name" "$install_type" "$version"
273
  fi
274
}
275

276
get_custom_executable_path() {
277
  local plugin_path=$1
278
  local install_path=$2
279
  local executable_path=$3
280

281
  # custom plugin hook for executable path
282
  if [ -x "${plugin_path}/bin/exec-path" ]; then
283
    cmd=$(basename "$executable_path")
284
    local relative_path
285
    # shellcheck disable=SC2001
286
    relative_path=$(printf "%s\n" "$executable_path" | sed -e "s|${install_path}/||")
287
    relative_path="$("${plugin_path}/bin/exec-path" "$install_path" "$cmd" "$relative_path")"
288
    executable_path="$install_path/$relative_path"
289
  fi
290

291
  printf "%s\n" "$executable_path"
292
}
293

294
get_executable_path() {
295
  local plugin_name=$1
296
  local version=$2
297
  local executable_path=$3
298

299
  check_if_version_exists "$plugin_name" "$version"
300

301
  if [ "$version" = "system" ]; then
302
    path=$(remove_path_from_path "$PATH" "$(asdf_data_dir)/shims")
303
    cmd=$(basename "$executable_path")
304
    cmd_path=$(PATH=$path command -v "$cmd" 2>&1)
305
    # shellcheck disable=SC2181
306
    if [ $? -ne 0 ]; then
307
      return 1
308
    fi
309
    printf "%s\n" "$cmd_path"
310
  else
311
    local install_path
312
    install_path=$(find_install_path "$plugin_name" "$version")
313
    printf "%s\n" "${install_path}"/"${executable_path}"
314
  fi
315
}
316

317
parse_asdf_version_file() {
318
  local file_path=$1
319
  local plugin_name=$2
320

321
  if [ -f "$file_path" ]; then
322
    local version
323
    version=$(strip_tool_version_comments "$file_path" | grep "^${plugin_name} " | sed -e "s/^${plugin_name} //")
324

325
    if [ -n "$version" ]; then
326
      if [[ "$version" == path:* ]]; then
327
        util_resolve_user_path "${version#path:}"
328
        printf "%s\n" "path:${util_resolve_user_path_reply}"
329
      else
330
        printf "%s\n" "$version"
331
      fi
332

333
      return 0
334
    fi
335
  fi
336
}
337

338
parse_legacy_version_file() {
339
  local file_path=$1
340
  local plugin_name=$2
341

342
  local plugin_path
343
  plugin_path=$(get_plugin_path "$plugin_name")
344
  local parse_legacy_script
345
  parse_legacy_script="${plugin_path}/bin/parse-legacy-file"
346

347
  if [ -f "$file_path" ]; then
348
    if [ -f "$parse_legacy_script" ]; then
349
      "$parse_legacy_script" "$file_path"
350
    else
351
      cat "$file_path"
352
    fi
353
  fi
354
}
355

356
get_preset_version_for() {
357
  local plugin_name=$1
358
  local search_path
359
  search_path=$PWD
360
  local version_and_path
361
  version_and_path=$(find_versions "$plugin_name" "$search_path")
362
  local version
363
  version=$(cut -d '|' -f 1 <<<"$version_and_path")
364

365
  printf "%s\n" "$version"
366
}
367

368
get_asdf_config_value_from_file() {
369
  local config_path=$1
370
  local key=$2
371

372
  if [ ! -f "$config_path" ]; then
373
    return 1
374
  fi
375

376
  util_validate_no_carriage_returns "$config_path"
377

378
  local result
379
  result=$(grep -E "^\s*$key\s*=\s*" "$config_path" | head | sed -e 's/^[^=]*= *//' -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
380
  if [ -n "$result" ]; then
381
    printf "%s\n" "$result"
382
    return 0
383
  fi
384

385
  return 2
386
}
387

388
get_asdf_config_value() {
389
  local key=$1
390
  local config_path=
391
  config_path=$(asdf_config_file)
392
  local default_config_path=${ASDF_CONFIG_DEFAULT_FILE:-"$(asdf_dir)/defaults"}
393

394
  local local_config_path
395
  local_config_path="$(find_file_upwards ".asdfrc")"
396

397
  get_asdf_config_value_from_file "$local_config_path" "$key" ||
398
    get_asdf_config_value_from_file "$config_path" "$key" ||
399
    get_asdf_config_value_from_file "$default_config_path" "$key"
400
}
401

402
# Whether the plugin shortname repo needs to be synced
403
# 0: if no sync needs to occur
404
# 1: if sync needs to occur
405
repository_needs_update() {
406
  local plugin_repository_last_check_duration
407
  local sync_required
408

409
  plugin_repository_last_check_duration="$(get_asdf_config_value "plugin_repository_last_check_duration")"
410

411
  if [ "never" != "$plugin_repository_last_check_duration" ]; then
412
    local update_file_dir
413
    local update_file_name
414
    update_file_dir="$(asdf_data_dir)/tmp"
415
    update_file_name="repo-updated"
416
    # `find` outputs filename if it has not been modified in plugin_repository_last_check_duration setting.
417
    sync_required=$(find "$update_file_dir" -name "$update_file_name" -type f -mmin +"${plugin_repository_last_check_duration:-60}" -print)
418
  fi
419

420
  [ "$sync_required" ]
421
}
422

423
initialize_or_update_plugin_repository() {
424
  local repository_url
425
  local repository_path
426

427
  disable_plugin_short_name_repo="$(get_asdf_config_value "disable_plugin_short_name_repository")"
428
  if [ "yes" = "$disable_plugin_short_name_repo" ]; then
429
    printf "Short-name plugin repository is disabled\n" >&2
430
    exit 1
431
  fi
432

433
  repository_url=$(asdf_plugin_repository_url)
434
  repository_path=$(asdf_data_dir)/repository
435

436
  if [ ! -d "$repository_path" ]; then
437
    printf "initializing plugin repository..."
438
    git clone "$repository_url" "$repository_path"
439
  elif repository_needs_update; then
440
    printf "updating plugin repository..."
441
    git -C "$repository_path" fetch
442
    git -C "$repository_path" reset --hard origin/master
443
  fi
444

445
  [ -d "$(asdf_data_dir)/tmp" ] || mkdir -p "$(asdf_data_dir)/tmp"
446
  touch "$(asdf_data_dir)/tmp/repo-updated"
447
}
448

449
get_plugin_source_url() {
450
  local plugin_name=$1
451
  local plugin_config
452

453
  plugin_config="$(asdf_data_dir)/repository/plugins/$plugin_name"
454

455
  if [ -f "$plugin_config" ]; then
456
    grep "repository" "$plugin_config" | awk -F'=' '{print $2}' | sed 's/ //'
457
  fi
458
}
459

460
find_tool_versions() {
461
  find_file_upwards "$(asdf_tool_versions_filename)"
462
}
463

464
find_file_upwards() {
465
  local name="$1"
466
  local search_path
467
  search_path=$PWD
468
  while [ "$search_path" != "/" ]; do
469
    if [ -f "$search_path/$name" ]; then
470
      util_validate_no_carriage_returns "$search_path/$name"
471

472
      printf "%s\n" "${search_path}/$name"
473
      return 0
474
    fi
475
    search_path=$(dirname "$search_path")
476
  done
477
}
478

479
resolve_symlink() {
480
  local symlink
481
  symlink="$1"
482

483
  # This seems to be the only cross-platform way to resolve symlink paths to
484
  # the real file path.
485
  # shellcheck disable=SC2012
486
  resolved_path=$(ls -l "$symlink" | sed -e 's|.*-> \(.*\)|\1|') # asdf_allow: ls '
487

488
  # Check if resolved path is relative or not by looking at the first character.
489
  # If it is a slash we can assume it's root and absolute. Otherwise we treat it
490
  # as relative
491
  case $resolved_path in
492
  /*)
493
    printf "%s\n" "$resolved_path"
494
    ;;
495
  *)
496
    (
497
      cd "$(dirname "$symlink")" || exit 1
498
      printf "%s\n" "$PWD/$resolved_path"
499
    )
500
    ;;
501
  esac
502
}
503

504
list_plugin_bin_paths() {
505
  local plugin_name=$1
506
  local version=$2
507
  local install_type=$3
508
  local plugin_path
509
  plugin_path=$(get_plugin_path "$plugin_name")
510
  local install_path
511
  install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
512

513
  if [ -f "${plugin_path}/bin/list-bin-paths" ]; then
514
    local space_separated_list_of_bin_paths
515

516
    # shellcheck disable=SC2030
517
    space_separated_list_of_bin_paths=$(
518
      export ASDF_INSTALL_TYPE=$install_type
519
      export ASDF_INSTALL_VERSION=$version
520
      export ASDF_INSTALL_PATH=$install_path
521
      "${plugin_path}/bin/list-bin-paths"
522
    )
523
  else
524
    local space_separated_list_of_bin_paths="bin"
525
  fi
526
  printf "%s\n" "$space_separated_list_of_bin_paths"
527
}
528

529
list_plugin_exec_paths() {
530
  local plugin_name=$1
531
  local full_version=$2
532
  check_if_plugin_exists "$plugin_name"
533

534
  IFS=':' read -r -a version_info <<<"$full_version"
535
  if [ "${version_info[0]}" = "ref" ]; then
536
    local install_type="${version_info[0]}"
537
    local version="${version_info[1]}"
538
  elif [ "${version_info[0]}" = "path" ]; then
539
    local install_type="${version_info[0]}"
540
    local version="${version_info[1]}"
541
  else
542
    local install_type="version"
543
    local version="${version_info[0]}"
544
  fi
545

546
  local plugin_shims_path
547
  plugin_shims_path=$(get_plugin_path "$plugin_name")/shims
548
  if [ -d "$plugin_shims_path" ]; then
549
    printf "%s\n" "$plugin_shims_path"
550
  fi
551

552
  space_separated_list_of_bin_paths="$(list_plugin_bin_paths "$plugin_name" "$version" "$install_type")"
553
  IFS=' ' read -r -a all_bin_paths <<<"$space_separated_list_of_bin_paths"
554

555
  local install_path
556
  install_path=$(get_install_path "$plugin_name" "$install_type" "$version")
557

558
  for bin_path in "${all_bin_paths[@]}"; do
559
    printf "%s\n" "$install_path/$bin_path"
560
  done
561
}
562

563
with_plugin_env() {
564
  local plugin_name=$1
565
  local full_version=$2
566
  local callback=$3
567

568
  IFS=':' read -r -a version_info <<<"$full_version"
569
  if [ "${version_info[0]}" = "ref" ]; then
570
    local install_type="${version_info[0]}"
571
    local version="${version_info[1]}"
572
  else
573
    local install_type="version"
574
    local version="${version_info[0]}"
575
  fi
576

577
  if [ "$version" = "system" ]; then
578
    # execute as is for system
579
    "$callback"
580
    return $?
581
  fi
582

583
  local plugin_path
584
  plugin_path=$(get_plugin_path "$plugin_name")
585

586
  # add the plugin listed exec paths to PATH
587
  local path exec_paths
588
  exec_paths="$(list_plugin_exec_paths "$plugin_name" "$full_version")"
589

590
  # exec_paths contains a trailing newline which is converted to a colon, so no
591
  # colon is needed between the subshell and the PATH variable in this string
592
  path="$(tr '\n' ':' <<<"$exec_paths")$PATH"
593

594
  # If no custom exec-env transform, just execute callback
595
  if [ ! -f "${plugin_path}/bin/exec-env" ]; then
596
    PATH=$path "$callback"
597
    return $?
598
  fi
599

600
  # Load the plugin custom environment
601
  local install_path
602
  install_path=$(find_install_path "$plugin_name" "$full_version")
603

604
  # shellcheck source=/dev/null
605
  ASDF_INSTALL_TYPE=$install_type \
606
    ASDF_INSTALL_VERSION=$version \
607
    ASDF_INSTALL_PATH=$install_path \
608
    . "${plugin_path}/bin/exec-env"
609

610
  PATH=$path "$callback"
611
}
612

613
plugin_executables() {
614
  local plugin_name=$1
615
  local full_version=$2
616
  local all_bin_paths
617
  IFS=$'\n' read -rd '' -a all_bin_paths <<<"$(list_plugin_exec_paths "$plugin_name" "$full_version")"
618
  for bin_path in "${all_bin_paths[@]}"; do
619
    for executable_file in "$bin_path"/*; do
620
      if is_executable "$executable_file"; then
621
        printf "%s\n" "$executable_file"
622
      fi
623
    done
624
  done
625
}
626

627
is_executable() {
628
  local executable_path=$1
629
  if [[ (-f "$executable_path") && (-x "$executable_path") ]]; then
630
    return 0
631
  fi
632
  return 1
633
}
634

635
plugin_shims() {
636
  local plugin_name=$1
637
  local full_version=$2
638
  grep -lx "# asdf-plugin: $plugin_name $full_version" "$(asdf_data_dir)/shims"/* 2>/dev/null
639
}
640

641
shim_plugin_versions() {
642
  local executable_name
643
  executable_name=$(basename "$1")
644
  local shim_path
645
  shim_path="$(asdf_data_dir)/shims/${executable_name}"
646
  if [ -x "$shim_path" ]; then
647
    grep "# asdf-plugin: " "$shim_path" 2>/dev/null | sed -e "s/# asdf-plugin: //" | uniq
648
  else
649
    printf "asdf: unknown shim %s\n" "$executable_name"
650
    return 1
651
  fi
652
}
653

654
shim_plugins() {
655
  local executable_name
656
  executable_name=$(basename "$1")
657
  local shim_path
658
  shim_path="$(asdf_data_dir)/shims/${executable_name}"
659
  if [ -x "$shim_path" ]; then
660
    grep "# asdf-plugin: " "$shim_path" 2>/dev/null | sed -e "s/# asdf-plugin: //" | cut -d' ' -f 1 | uniq
661
  else
662
    printf "asdf: unknown shim %s\n" "$executable_name"
663
    return 1
664
  fi
665
}
666

667
strip_tool_version_comments() {
668
  local tool_version_path="$1"
669
  # Use sed to strip comments from the tool version file
670
  # Breakdown of sed command:
671
  # This command represents 3 steps, separated by a semi-colon (;), that run on each line.
672
  # 1. Delete line if it starts with any blankspace and a #.
673
  # 2. Find a # and delete it and everything after the #.
674
  # 3. Remove any whitespace from the end of the line.
675
  # Finally, the command will print the lines that are not empty.
676
  sed '/^[[:blank:]]*#/d;s/#.*//;s/[[:blank:]]*$//' "$tool_version_path"
677
}
678

679
asdf_run_hook() {
680
  local hook_name=$1
681
  local hook_cmd
682
  hook_cmd="$(get_asdf_config_value "$hook_name")"
683
  if [ -n "$hook_cmd" ]; then
684
    asdf_hook_fun() {
685
      unset asdf_hook_fun
686
      ev'al' "$hook_cmd" # ignore banned command just here
687
    }
688
    asdf_hook_fun "${@:2}"
689
  fi
690
}
691

692
get_shim_versions() {
693
  shim_name=$1
694
  shim_plugin_versions "${shim_name}"
695
  shim_plugin_versions "${shim_name}" | cut -d' ' -f 1 | awk '{print$1" system"}'
696
}
697

698
preset_versions() {
699
  shim_name=$1
700
  shim_plugin_versions "${shim_name}" | cut -d' ' -f 1 | uniq | xargs -IPLUGIN bash -c ". $(asdf_dir)/lib/utils.bash; printf \"%s %s\n\" PLUGIN \$(get_preset_version_for PLUGIN)"
701
}
702

703
select_from_preset_version() {
704
  local shim_name=$1
705
  local shim_versions
706
  local preset_versions
707

708
  shim_versions=$(get_shim_versions "$shim_name")
709
  if [ -n "$shim_versions" ]; then
710
    preset_versions=$(preset_versions "$shim_name")
711
    grep -F "$shim_versions" <<<"$preset_versions" | head -n 1 | xargs -IVERSION printf "%s\n" VERSION
712
  fi
713
}
714

715
select_version() {
716
  shim_name=$1
717
  # First, we get the all the plugins where the
718
  # current shim is available.
719
  # Then, we iterate on all versions set for each plugin
720
  # Note that multiple plugin versions can be set for a single plugin.
721
  # These are separated by a space. e.g. python 3.7.2 2.7.15
722
  # For each plugin/version pair, we check if it is present in the shim
723
  local search_path
724
  search_path=$PWD
725
  local shim_versions
726
  IFS=$'\n' read -rd '' -a shim_versions <<<"$(get_shim_versions "$shim_name")"
727

728
  local plugins
729
  IFS=$'\n' read -rd '' -a plugins <<<"$(shim_plugins "$shim_name")"
730

731
  for plugin_name in "${plugins[@]}"; do
732
    local version_and_path
733
    local version_string
734
    local usable_plugin_versions
735
    local _path
736
    version_and_path=$(find_versions "$plugin_name" "$search_path")
737
    IFS='|' read -r version_string _path <<<"$version_and_path"
738
    IFS=' ' read -r -a usable_plugin_versions <<<"$version_string"
739
    for plugin_version in "${usable_plugin_versions[@]}"; do
740
      for plugin_and_version in "${shim_versions[@]}"; do
741
        local plugin_shim_name
742
        local plugin_shim_version
743
        IFS=' ' read -r plugin_shim_name plugin_shim_version <<<"$plugin_and_version"
744
        if [[ "$plugin_name" == "$plugin_shim_name" ]]; then
745
          if [[ "$plugin_version" == "$plugin_shim_version" ]]; then
746
            printf "%s\n" "$plugin_name $plugin_version"
747
            return
748
          elif [[ "$plugin_version" == "path:"* ]]; then
749
            printf "%s\n" "$plugin_name $plugin_version"
750
            return
751
          fi
752
        fi
753
      done
754
    done
755
  done
756
}
757

758
with_shim_executable() {
759
  local shim_name
760
  shim_name=$(basename "$1")
761
  local shim_exec="${2}"
762

763
  if [ ! -f "$(asdf_data_dir)/shims/${shim_name}" ]; then
764
    printf "%s %s %s\n" "unknown command:" "${shim_name}." "Perhaps you have to reshim?" >&2
765
    return 1
766
  fi
767

768
  local selected_version
769
  selected_version="$(select_version "$shim_name")"
770

771
  if [ -z "$selected_version" ]; then
772
    selected_version="$(select_from_preset_version "$shim_name")"
773
  fi
774

775
  if [ -n "$selected_version" ]; then
776
    local plugin_name
777
    local full_version
778
    local plugin_path
779

780
    IFS=' ' read -r plugin_name full_version <<<"$selected_version"
781
    plugin_path=$(get_plugin_path "$plugin_name")
782

783
    # This function does get invoked, but shellcheck sees it as unused code
784
    # shellcheck disable=SC2317
785
    run_within_env() {
786
      local path
787
      path=$(remove_path_from_path "$PATH" "$(asdf_data_dir)/shims")
788

789
      executable_path=$(PATH=$path command -v "$shim_name")
790

791
      if [ -x "${plugin_path}/bin/exec-path" ]; then
792
        install_path=$(find_install_path "$plugin_name" "$full_version")
793
        executable_path=$(get_custom_executable_path "${plugin_path}" "${install_path}" "${executable_path:-${shim_name}}")
794
      fi
795

796
      "$shim_exec" "$plugin_name" "$full_version" "$executable_path"
797
    }
798

799
    with_plugin_env "$plugin_name" "$full_version" run_within_env
800
    return $?
801
  fi
802

803
  (
804
    local preset_plugin_versions
805
    preset_plugin_versions=()
806
    local closest_tool_version
807
    closest_tool_version=$(find_tool_versions)
808

809
    local shim_plugins
810
    IFS=$'\n' read -rd '' -a shim_plugins <<<"$(shim_plugins "$shim_name")"
811
    for shim_plugin in "${shim_plugins[@]}"; do
812
      local shim_versions
813
      local version_string
814
      version_string=$(get_preset_version_for "$shim_plugin")
815
      IFS=' ' read -r -a shim_versions <<<"$version_string"
816
      local usable_plugin_versions
817
      for shim_version in "${shim_versions[@]}"; do
818
        preset_plugin_versions+=("$shim_plugin $shim_version")
819
      done
820
    done
821

822
    if [ -n "${preset_plugin_versions[*]}" ]; then
823
      printf "%s %s\n" "No preset version installed for command" "$shim_name"
824
      printf "%s\n\n" "Please install a version by running one of the following:"
825
      for preset_plugin_version in "${preset_plugin_versions[@]}"; do
826
        printf "%s %s\n" "asdf install" "$preset_plugin_version"
827
      done
828
      printf "\n%s %s\n" "or add one of the following versions in your config file at" "$closest_tool_version"
829
    else
830
      printf "%s %s\n" "No version is set for command" "$shim_name"
831
      printf "%s %s\n" "Consider adding one of the following versions in your config file at" "$closest_tool_version"
832
    fi
833
    shim_plugin_versions "${shim_name}"
834
  ) >&2
835

836
  return 126
837
}
838

839
substitute() {
840
  # Use Bash substitution rather than sed as it will handle escaping of all
841
  # strings for us.
842
  local input=$1
843
  local find_str=$2
844
  local replace=$3
845
  printf "%s" "${input//"$find_str"/"$replace"}"
846
}
847

848
remove_path_from_path() {
849
  # A helper function for removing an arbitrary path from the PATH variable.
850
  # Output is a new string suitable for assignment to PATH
851
  local PATH=$1
852
  local path=$2
853
  substitute "$PATH" "$path" "" | sed -e "s|::|:|g"
854
}
855

856
# @description Strings that began with a ~ are always paths. In
857
# that case, then ensure ~ it handled like a shell
858
util_resolve_user_path() {
859
  util_resolve_user_path_reply=
860
  local path="$1"
861

862
  # shellcheck disable=SC2088
863
  if [ "${path::2}" = '~/' ]; then
864
    util_resolve_user_path_reply="${HOME}/${path:2}"
865
  else
866
    util_resolve_user_path_reply="$path"
867
  fi
868
}
869

870
# @description Check if a file contains carriage returns. If it does, print a warning.
871
util_validate_no_carriage_returns() {
872
  local file_path="$1"
873

874
  if grep -qr $'\r' "$file_path"; then
875
    printf '%s\n' "asdf: Warning: File $file_path contains carriage returns. Please remove them." >&2
876
  fi
877
}
878

879
get_plugin_remote_url() {
880
  local plugin_name="$1"
881
  local plugin_path
882
  plugin_path="$(get_plugin_path "$plugin_name")"
883
  git --git-dir "$plugin_path/.git" remote get-url origin 2>/dev/null
884
}
885

886
get_plugin_remote_branch() {
887
  local plugin_name="$1"
888
  local plugin_path
889
  plugin_path="$(get_plugin_path "$plugin_name")"
890
  git --git-dir "$plugin_path/.git" rev-parse --abbrev-ref HEAD 2>/dev/null
891
}
892

893
get_plugin_remote_gitref() {
894
  local plugin_name="$1"
895
  local plugin_path
896
  plugin_path="$(get_plugin_path "$plugin_name")"
897
  git --git-dir "$plugin_path/.git" rev-parse --short HEAD 2>/dev/null
898
}
899

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.