oh-my-devpod 0.14.2 → 0.14.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -188,9 +188,8 @@ omd_module_brew_cmd() {
188
188
  return 1
189
189
  }
190
190
 
191
- omd_module_brew_formula_installed() {
192
- local formula="$1" formula_name prefix cellar version
193
- prefix="$(omd_module_brew_prefix)" || return 1
191
+ omd_module_brew_formula_installed_at() {
192
+ local prefix="$1" formula="$2" formula_name cellar version
194
193
  formula_name="${formula##*/}"
195
194
  cellar="${prefix}/Cellar/${formula_name}"
196
195
  [[ -d "${cellar}" ]] || return 1
@@ -200,16 +199,40 @@ omd_module_brew_formula_installed() {
200
199
  return 1
201
200
  }
202
201
 
202
+ omd_module_brew_formula_installed() {
203
+ local formula="$1" prefix
204
+ prefix="$(omd_module_brew_prefix)" || return 1
205
+ omd_module_brew_formula_installed_at "${prefix}" "${formula}"
206
+ }
207
+
208
+ omd_module_brew_prefix_for_cmd() {
209
+ local brew="$1" prefix
210
+ prefix="$(omd_module_brew_exec "${brew}" --prefix 2>/dev/null || true)"
211
+ if [[ "${prefix}" == /* && -d "${prefix}" ]]; then
212
+ cd "${prefix}" 2>/dev/null && pwd -P
213
+ return
214
+ fi
215
+ [[ "${brew}" == */bin/brew ]] || return 1
216
+ cd "$(dirname "${brew}")/.." 2>/dev/null && pwd -P
217
+ }
218
+
219
+ omd_module_brew_cmd_matches_prefix() {
220
+ local brew="$1" expected_prefix="$2" resolved_brew reported_prefix
221
+ expected_prefix="$(cd "${expected_prefix}" 2>/dev/null && pwd -P)" || return 1
222
+ if [[ -L "${brew}" ]]; then
223
+ command -v readlink >/dev/null 2>&1 || return 1
224
+ resolved_brew="$(readlink -f "${brew}" 2>/dev/null || true)"
225
+ [[ "${resolved_brew}" == "${expected_prefix}"/* ]] || return 1
226
+ fi
227
+ reported_prefix="$(omd_module_brew_prefix_for_cmd "${brew}")" || return 1
228
+ [[ "${reported_prefix}" == "${expected_prefix}" ]]
229
+ }
230
+
203
231
  omd_module_brew_prefix() {
204
- local brew resolved
232
+ local brew
205
233
  brew="$(omd_module_brew_cmd)" || return 1
206
- if command -v readlink >/dev/null 2>&1; then
207
- resolved="$(readlink -f "${brew}" 2>/dev/null || true)"
208
- [[ -z "${resolved}" ]] || brew="${resolved}"
209
- fi
210
- if [[ "${brew}" == */bin/brew ]]; then
211
- cd "$(dirname "${brew}")/.." 2>/dev/null && pwd -P
212
- return
234
+ if omd_module_brew_prefix_for_cmd "${brew}"; then
235
+ return 0
213
236
  fi
214
237
  if [[ -n "${HOMEBREW_PREFIX:-}" && -d "${HOMEBREW_PREFIX}" ]]; then
215
238
  printf '%s\n' "${HOMEBREW_PREFIX}"
@@ -231,9 +254,10 @@ omd_module_brew_exec() {
231
254
  }
232
255
 
233
256
  omd_module_formula_status() {
234
- local formula="$1" command_name="$2"
257
+ local formula="$1" command_name="$2" prefix
235
258
  if [[ -n "${component:-}" ]] && omd_module_formula_managed "${component}" "${formula}"; then
236
- omd_module_brew_formula_installed "${formula}"
259
+ prefix="$(omd_module_formula_marker_prefix "${component}" "${formula}")" || return 1
260
+ omd_module_brew_formula_installed_at "${prefix}" "${formula}"
237
261
  return
238
262
  fi
239
263
  command -v "${command_name}" >/dev/null 2>&1 ||
@@ -241,12 +265,40 @@ omd_module_formula_status() {
241
265
  }
242
266
 
243
267
  omd_module_formula_managed() {
244
- local component="$1" formula="$2"
245
- omd_module_marker_matches "${component}" "${formula}"
268
+ local component="$1" formula="$2" kind
269
+ omd_module_marker_matches "${component}" "${formula}" || return 1
270
+ kind="$(omd_module_marker_value "${component}" kind || true)"
271
+ [[ "${kind}" == "brew-formula" ]]
272
+ }
273
+
274
+ omd_module_formula_marker_prefix() {
275
+ local component="$1" formula="$2" prefix linuxbrew_kind
276
+ omd_module_formula_managed "${component}" "${formula}" || return 1
277
+ prefix="$(omd_module_marker_value "${component}" brew_prefix || true)"
278
+ if [[ -z "${prefix}" ]] && omd_module_is_managed linuxbrew; then
279
+ linuxbrew_kind="$(omd_module_marker_value linuxbrew kind || true)"
280
+ if [[ "${linuxbrew_kind}" == "directory" ]]; then
281
+ prefix="$(omd_module_marker_value linuxbrew artifact || true)"
282
+ if ! omd_module_brew_formula_installed_at "${prefix}" "${formula}"; then
283
+ prefix=""
284
+ fi
285
+ fi
286
+ fi
287
+ [[ -n "${prefix}" && "${prefix}" == /* && ! -L "${prefix}" && -x "${prefix}/bin/brew" ]] ||
288
+ return 1
289
+ prefix="$(cd "${prefix}" 2>/dev/null && pwd -P)" || return 1
290
+ omd_module_brew_cmd_matches_prefix "${prefix}/bin/brew" "${prefix}" || return 1
291
+ printf '%s\n' "${prefix}"
292
+ }
293
+
294
+ omd_module_formula_brew_cmd() {
295
+ local component="$1" formula="$2" prefix
296
+ prefix="$(omd_module_formula_marker_prefix "${component}" "${formula}")" || return 1
297
+ printf '%s/bin/brew\n' "${prefix}"
246
298
  }
247
299
 
248
300
  omd_module_formula_install_or_update() {
249
- local component="$1" formula="$2" command_name="$3" action="$4"
301
+ local component="$1" formula="$2" command_name="$3" action="$4" brew brew_prefix
250
302
  shift 4
251
303
  omd_module_reject_unknown_flags "$@" || return
252
304
 
@@ -261,24 +313,38 @@ omd_module_formula_install_or_update() {
261
313
  return 0
262
314
  fi
263
315
 
264
- local brew
265
- brew="$(omd_module_brew_cmd)" || {
266
- omd_module_info error "Linuxbrew is required before ${component}"
316
+ if omd_module_formula_managed "${component}" "${formula}"; then
317
+ brew="$(omd_module_formula_brew_cmd "${component}" "${formula}")" || {
318
+ omd_module_info error "managed ${component} has no valid owning Homebrew prefix"
319
+ return 1
320
+ }
321
+ else
322
+ brew="$(omd_module_brew_cmd)" || {
323
+ omd_module_info error "Linuxbrew is required before ${component}"
324
+ return 1
325
+ }
326
+ fi
327
+ brew_prefix="$(omd_module_brew_prefix_for_cmd "${brew}")" || {
328
+ omd_module_info error "could not determine Homebrew prefix for ${component}"
267
329
  return 1
268
330
  }
269
331
 
270
332
  if [[ "${action}" == "update" ]] &&
271
- omd_module_brew_exec "${brew}" list --formula "${formula}" >/dev/null 2>&1; then
333
+ omd_module_brew_formula_installed_at "${brew_prefix}" "${formula}"; then
272
334
  omd_module_brew_exec "${brew}" upgrade "${formula}"
273
335
  else
274
336
  omd_module_brew_exec "${brew}" install "${formula}"
275
337
  fi
276
- omd_module_mark_managed "${component}" brew-formula "${formula}"
338
+ omd_module_mark_managed \
339
+ "${component}" \
340
+ brew-formula \
341
+ "${formula}" \
342
+ "brew_prefix=${brew_prefix}"
277
343
  }
278
344
 
279
- omd_module_formula_uninstall() {
280
- local component="$1" formula="$2"
281
- shift 2
345
+ omd_module_formula_uninstall_impl() {
346
+ local component="$1" formula="$2" remove_marker="$3"
347
+ shift 3
282
348
  omd_module_reject_unknown_flags "$@" || return
283
349
 
284
350
  if omd_module_dry_run "$@"; then
@@ -289,11 +355,18 @@ omd_module_formula_uninstall() {
289
355
  omd_module_formula_managed "${component}" "${formula}" ||
290
356
  omd_module_refuse_unmanaged "${component}" || return
291
357
 
292
- local brew dependants
293
- brew="$(omd_module_brew_cmd)" || {
294
- omd_module_info error "Linuxbrew is required to uninstall ${component}"
358
+ local brew brew_prefix dependants
359
+ brew="$(omd_module_formula_brew_cmd "${component}" "${formula}")" || {
360
+ omd_module_info error "managed ${component} has no valid owning Homebrew prefix"
295
361
  return 1
296
362
  }
363
+ brew_prefix="$(omd_module_brew_prefix_for_cmd "${brew}")" || return 1
364
+ if ! omd_module_brew_formula_installed_at "${brew_prefix}" "${formula}"; then
365
+ if [[ "${remove_marker}" == "1" ]]; then
366
+ omd_module_unmark_managed "${component}"
367
+ fi
368
+ return 0
369
+ fi
297
370
  if ! dependants="$(omd_module_brew_exec "${brew}" uses --installed "${formula}" 2>&1)"; then
298
371
  omd_module_info error "failed to inspect Homebrew dependants for ${component}: ${dependants}"
299
372
  return 1
@@ -303,7 +376,21 @@ omd_module_formula_uninstall() {
303
376
  return 1
304
377
  fi
305
378
  omd_module_brew_exec "${brew}" uninstall "${formula}"
306
- omd_module_unmark_managed "${component}"
379
+ if [[ "${remove_marker}" == "1" ]]; then
380
+ omd_module_unmark_managed "${component}"
381
+ fi
382
+ }
383
+
384
+ omd_module_formula_uninstall() {
385
+ local component="$1" formula="$2"
386
+ shift 2
387
+ omd_module_formula_uninstall_impl "${component}" "${formula}" 1 "$@"
388
+ }
389
+
390
+ omd_module_formula_uninstall_keep_marker() {
391
+ local component="$1" formula="$2"
392
+ shift 2
393
+ omd_module_formula_uninstall_impl "${component}" "${formula}" 0 "$@"
307
394
  }
308
395
 
309
396
  omd_module_zsh_path() {
@@ -2,12 +2,28 @@
2
2
  set -euo pipefail
3
3
 
4
4
  source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
5
+ # shellcheck source=source-config.sh
6
+ source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/source-config.sh"
5
7
 
6
8
  case "${1:-}" in
7
9
  install|update) ;;
8
10
  *) omd_module_unknown_action "${1:-}" ;;
9
11
  esac
10
12
 
13
+ case "${OHMYDEVPOD_MIRROR_PROFILE:-upstream}" in
14
+ cn) source_name="gitee" ;;
15
+ upstream) source_name="github" ;;
16
+ *)
17
+ omd_module_info notice "unknown mirror profile; native source configuration was not changed"
18
+ source_name=""
19
+ ;;
20
+ esac
21
+ if [[ -n "${source_name}" ]] &&
22
+ ! omd_source_config_apply_transactional "${source_name}"; then
23
+ omd_module_info error "failed to apply native source configuration"
24
+ exit 1
25
+ fi
26
+
11
27
  if ! omd_module_is_managed zsh && ! omd_module_is_managed zsh-config; then
12
28
  exit 0
13
29
  fi
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
5
+
6
+ omd_source_config_header="# Generated by oh-my-devpod. Managed native source configuration."
7
+
8
+ omd_source_config_path_is_safe() {
9
+ local path="$1" trusted_root="$2" current parent
10
+ [[ "${path}" == /* && "${trusted_root}" == /* ]] || return 1
11
+ [[ "${path}" == "${trusted_root}"/* ]] || return 1
12
+ [[ ! -L "${path}" ]] || return 1
13
+ current="$(dirname "${path}")"
14
+ while [[ "${current}" != "${trusted_root}" ]]; do
15
+ [[ ! -L "${current}" ]] || return 1
16
+ parent="$(dirname "${current}")"
17
+ [[ "${parent}" != "${current}" ]] || return 1
18
+ current="${parent}"
19
+ done
20
+ }
21
+
22
+ omd_source_config_atomic_write() {
23
+ local destination="$1" trusted_root="$2" directory temporary
24
+ omd_source_config_path_is_safe "${destination}" "${trusted_root}" || {
25
+ omd_module_info error "refusing unsafe source configuration path: ${destination}"
26
+ return 1
27
+ }
28
+ directory="$(dirname "${destination}")"
29
+ mkdir -p "${directory}" || return 1
30
+ temporary="$(mktemp "${directory}/.$(basename "${destination}").tmp.XXXXXX")" ||
31
+ return 1
32
+ if ! cat > "${temporary}"; then
33
+ rm -f "${temporary}"
34
+ return 1
35
+ fi
36
+ if ! mv -f "${temporary}" "${destination}"; then
37
+ rm -f "${temporary}"
38
+ return 1
39
+ fi
40
+ }
41
+
42
+ omd_source_config_formula_prefix() {
43
+ local component="$1" formula="$2" prefix
44
+ prefix="$(omd_module_formula_marker_prefix "${component}" "${formula}")" || return 1
45
+ omd_module_brew_formula_installed_at "${prefix}" "${formula}" || return 1
46
+ printf '%s\n' "${prefix}"
47
+ }
48
+
49
+ omd_source_config_formula_managed() {
50
+ omd_source_config_formula_prefix "$1" "$2" >/dev/null
51
+ }
52
+
53
+ omd_source_config_linuxbrew_prefix() {
54
+ local prefix kind
55
+ omd_module_is_managed linuxbrew || return 1
56
+ prefix="$(omd_module_marker_value linuxbrew artifact || true)"
57
+ kind="$(omd_module_marker_value linuxbrew kind || true)"
58
+ [[ "${kind}" == "directory" && -n "${prefix}" && ! -L "${prefix}" && -x "${prefix}/bin/brew" ]] ||
59
+ return 1
60
+ prefix="$(cd "${prefix}" 2>/dev/null && pwd -P)" || return 1
61
+ omd_module_brew_cmd_matches_prefix "${prefix}/bin/brew" "${prefix}" || return 1
62
+ printf '%s\n' "${prefix}"
63
+ }
64
+
65
+ omd_source_config_uv_path() {
66
+ printf '%s/uv/uv.toml\n' "${XDG_CONFIG_HOME:-${HOME}/.config}"
67
+ }
68
+
69
+ omd_source_config_config_home() {
70
+ printf '%s\n' "${XDG_CONFIG_HOME:-${HOME}/.config}"
71
+ }
72
+
73
+ omd_source_config_pip_path() {
74
+ printf '%s/pip/pip.conf\n' "${XDG_CONFIG_HOME:-${HOME}/.config}"
75
+ }
76
+
77
+ omd_source_config_mamba_path() {
78
+ printf '%s/.mambarc\n' "${HOME}"
79
+ }
80
+
81
+ omd_source_config_expected() {
82
+ local kind="$1"
83
+ case "${kind}" in
84
+ brew)
85
+ cat <<EOF
86
+ ${omd_source_config_header}
87
+ HOMEBREW_BREW_GIT_REMOTE=https://mirrors.ustc.edu.cn/brew.git
88
+ HOMEBREW_CORE_GIT_REMOTE=https://mirrors.ustc.edu.cn/homebrew-core.git
89
+ HOMEBREW_API_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles/api
90
+ HOMEBREW_BOTTLE_DOMAIN=https://mirrors.ustc.edu.cn/homebrew-bottles
91
+ EOF
92
+ ;;
93
+ uv)
94
+ cat <<EOF
95
+ ${omd_source_config_header}
96
+ [[index]]
97
+ url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
98
+ default = true
99
+ EOF
100
+ ;;
101
+ pip)
102
+ cat <<EOF
103
+ ${omd_source_config_header}
104
+ [global]
105
+ index-url = https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
106
+ EOF
107
+ ;;
108
+ mamba)
109
+ cat <<EOF
110
+ ${omd_source_config_header}
111
+ channel_alias: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
112
+ default_channels:
113
+ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
114
+ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
115
+ channels:
116
+ - conda-forge
117
+ EOF
118
+ ;;
119
+ *)
120
+ return 2
121
+ ;;
122
+ esac
123
+ }
124
+
125
+ omd_source_config_file_is_managed() {
126
+ local kind="$1" path="$2" actual expected
127
+ [[ -f "${path}" && ! -L "${path}" ]] || return 1
128
+ actual="$(cat "${path}")" || return 1
129
+ expected="$(omd_source_config_expected "${kind}")" || return 1
130
+ [[ "${actual}" == "${expected}" ]]
131
+ }
132
+
133
+ omd_source_config_active_paths() {
134
+ local prefix need_pip=0
135
+ if prefix="$(omd_source_config_linuxbrew_prefix)"; then
136
+ printf 'brew\t%s/etc/homebrew/brew.env\t%s\n' "${prefix}" "${prefix}"
137
+ fi
138
+ if omd_source_config_formula_managed uv uv; then
139
+ printf 'uv\t%s\t%s\n' \
140
+ "$(omd_source_config_uv_path)" \
141
+ "$(omd_source_config_config_home)"
142
+ need_pip=1
143
+ fi
144
+ if omd_source_config_formula_managed micromamba micromamba; then
145
+ printf 'mamba\t%s\t%s\n' "$(omd_source_config_mamba_path)" "${HOME}"
146
+ need_pip=1
147
+ fi
148
+ if [[ "${need_pip}" == "1" ]]; then
149
+ printf 'pip\t%s\t%s\n' \
150
+ "$(omd_source_config_pip_path)" \
151
+ "$(omd_source_config_config_home)"
152
+ fi
153
+ }
154
+
155
+ omd_source_config_validate() {
156
+ local source="$1" kind path trusted_root
157
+ case "${source}" in
158
+ github|gitee) ;;
159
+ *) return 2 ;;
160
+ esac
161
+
162
+ while IFS=$'\t' read -r kind path trusted_root; do
163
+ [[ -n "${kind}" && -n "${path}" && -n "${trusted_root}" ]] || continue
164
+ if ! omd_source_config_path_is_safe "${path}" "${trusted_root}"; then
165
+ omd_module_info error "refusing unsafe source configuration path: ${path}"
166
+ return 1
167
+ fi
168
+ if [[ -e "${path}" || -L "${path}" ]] &&
169
+ ! omd_source_config_file_is_managed "${kind}" "${path}"; then
170
+ omd_module_info error "refusing to overwrite user-modified source configuration: ${path}"
171
+ return 1
172
+ fi
173
+ done < <(omd_source_config_active_paths)
174
+ }
175
+
176
+ omd_source_config_apply() {
177
+ local source="$1" kind path trusted_root
178
+ omd_source_config_validate "${source}" || return
179
+
180
+ while IFS=$'\t' read -r kind path trusted_root; do
181
+ [[ -n "${kind}" && -n "${path}" && -n "${trusted_root}" ]] || continue
182
+ if [[ "${source}" == "gitee" ]]; then
183
+ omd_source_config_expected "${kind}" |
184
+ omd_source_config_atomic_write "${path}" "${trusted_root}" ||
185
+ return 1
186
+ else
187
+ if [[ -e "${path}" || -L "${path}" ]]; then
188
+ rm -f "${path}" || return 1
189
+ fi
190
+ fi
191
+ done < <(omd_source_config_active_paths)
192
+ }
193
+
194
+ omd_source_config_apply_transactional() {
195
+ local source="$1" transaction_root transaction_dir rollback_failed=0
196
+ transaction_root="${OHMYDEVPOD_SOURCE_CONFIG_TRANSACTION_ROOT:-$(omd_module_state_dir)}"
197
+ mkdir -p "${transaction_root}" || return 1
198
+ transaction_dir="$(mktemp -d "${transaction_root}/.source-config.XXXXXXXX")" ||
199
+ return 1
200
+ if ! omd_source_config_validate "${source}" ||
201
+ ! omd_source_config_snapshot "${transaction_dir}"; then
202
+ rm -rf "${transaction_dir}"
203
+ return 1
204
+ fi
205
+ if omd_source_config_apply "${source}"; then
206
+ rm -rf "${transaction_dir}"
207
+ return 0
208
+ fi
209
+ omd_source_config_restore "${transaction_dir}" || rollback_failed=1
210
+ if [[ "${rollback_failed}" == "0" ]]; then
211
+ rm -rf "${transaction_dir}"
212
+ else
213
+ omd_module_info error "native source rollback was incomplete: ${transaction_dir}"
214
+ fi
215
+ return 1
216
+ }
217
+
218
+ omd_source_config_snapshot() {
219
+ local snapshot_dir="$1" kind path trusted_root
220
+ mkdir -p "${snapshot_dir}" || return 1
221
+ : > "${snapshot_dir}/native-paths"
222
+ while IFS=$'\t' read -r kind path trusted_root; do
223
+ [[ -n "${kind}" && -n "${path}" && -n "${trusted_root}" ]] || continue
224
+ printf '%s\t%s\t%s\n' "${kind}" "${path}" "${trusted_root}" \
225
+ >> "${snapshot_dir}/native-paths"
226
+ if [[ -f "${path}" ]]; then
227
+ cp -p "${path}" "${snapshot_dir}/native-${kind}" || return 1
228
+ else
229
+ : > "${snapshot_dir}/.missing-native-${kind}" || return 1
230
+ fi
231
+ done < <(omd_source_config_active_paths)
232
+ }
233
+
234
+ omd_source_config_restore() {
235
+ local snapshot_dir="$1" kind path trusted_root
236
+ [[ -f "${snapshot_dir}/native-paths" ]] || return 0
237
+ while IFS=$'\t' read -r kind path trusted_root; do
238
+ [[ -n "${kind}" && -n "${path}" && -n "${trusted_root}" ]] || continue
239
+ if ! omd_source_config_path_is_safe "${path}" "${trusted_root}"; then
240
+ omd_module_info error "refusing unsafe source configuration rollback path: ${path}"
241
+ return 1
242
+ fi
243
+ if [[ -f "${snapshot_dir}/.missing-native-${kind}" ]]; then
244
+ if [[ -e "${path}" || -L "${path}" ]] &&
245
+ ! omd_source_config_file_is_managed "${kind}" "${path}"; then
246
+ omd_module_info error "refusing to remove changed source configuration during rollback: ${path}"
247
+ return 1
248
+ fi
249
+ if [[ -e "${path}" || -L "${path}" ]]; then
250
+ rm -f "${path}" || return 1
251
+ fi
252
+ else
253
+ cat "${snapshot_dir}/native-${kind}" |
254
+ omd_source_config_atomic_write "${path}" "${trusted_root}" ||
255
+ return 1
256
+ fi
257
+ done < "${snapshot_dir}/native-paths"
258
+ }
259
+
260
+ omd_source_config_remove_managed_file() {
261
+ local kind="$1" path="$2" trusted_root="$3"
262
+ [[ -e "${path}" || -L "${path}" ]] || return 0
263
+ if ! omd_source_config_path_is_safe "${path}" "${trusted_root}"; then
264
+ omd_module_info notice "preserving unsafe source configuration path: ${path}"
265
+ return 0
266
+ fi
267
+ if omd_source_config_file_is_managed "${kind}" "${path}"; then
268
+ rm -f "${path}"
269
+ else
270
+ omd_module_info notice "preserving modified source configuration: ${path}"
271
+ fi
272
+ }
273
+
274
+ omd_source_config_remove_component() {
275
+ local component="$1"
276
+ case "${component}" in
277
+ uv)
278
+ omd_source_config_remove_managed_file \
279
+ uv \
280
+ "$(omd_source_config_uv_path)" \
281
+ "$(omd_source_config_config_home)" ||
282
+ return 1
283
+ if ! omd_source_config_formula_managed micromamba micromamba; then
284
+ omd_source_config_remove_managed_file \
285
+ pip \
286
+ "$(omd_source_config_pip_path)" \
287
+ "$(omd_source_config_config_home)"
288
+ fi
289
+ ;;
290
+ micromamba)
291
+ omd_source_config_remove_managed_file \
292
+ mamba \
293
+ "$(omd_source_config_mamba_path)" \
294
+ "${HOME}" ||
295
+ return 1
296
+ if ! omd_source_config_formula_managed uv uv; then
297
+ omd_source_config_remove_managed_file \
298
+ pip \
299
+ "$(omd_source_config_pip_path)" \
300
+ "$(omd_source_config_config_home)"
301
+ fi
302
+ ;;
303
+ *)
304
+ return 2
305
+ ;;
306
+ esac
307
+ }
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/lib/common.sh"
5
+
6
+ component="gh"
7
+ formula="gh"
8
+ command_name="gh"
9
+
10
+ status() { omd_module_formula_status "${formula}" "${command_name}"; }
11
+ managed() { omd_module_formula_managed "${component}" "${formula}"; }
12
+ install_or_update() {
13
+ local action="$1"
14
+ shift
15
+ omd_module_formula_install_or_update "${component}" "${formula}" "${command_name}" "${action}" "$@"
16
+ }
17
+ uninstall() { omd_module_formula_uninstall "${component}" "${formula}" "$@"; }
18
+
19
+ case "${1:-}" in
20
+ status) status ;;
21
+ managed) managed ;;
22
+ install) shift; install_or_update install "$@" ;;
23
+ update) shift; install_or_update update "$@" ;;
24
+ uninstall) shift; uninstall "$@" ;;
25
+ *) omd_module_unknown_action "${1:-}" ;;
26
+ esac
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/lib/common.sh"
5
+
6
+ component="gitee"
7
+ bin_path="$(omd_module_bin_dir)/gitee"
8
+
9
+ marked() {
10
+ omd_module_marker_matches "${component}" "${bin_path}"
11
+ }
12
+
13
+ binary_matches_marker() {
14
+ local expected actual
15
+ [[ -f "${bin_path}" && -x "${bin_path}" ]] || return 1
16
+ expected="$(omd_module_marker_value "${component}" binary_sha256)" || return 1
17
+ [[ "${expected}" =~ ^[[:xdigit:]]{64}$ ]] || return 1
18
+ actual="$(omd_module_sha256_file "${bin_path}")" || return 1
19
+ [[ "${actual}" == "${expected}" ]]
20
+ }
21
+
22
+ status() {
23
+ if marked; then
24
+ [[ -f "${bin_path}" && -x "${bin_path}" ]]
25
+ else
26
+ command -v gitee >/dev/null 2>&1 ||
27
+ [[ -f "${bin_path}" && -x "${bin_path}" ]]
28
+ fi
29
+ }
30
+
31
+ managed() {
32
+ marked || return 1
33
+ [[ ! -e "${bin_path}" ]] || binary_matches_marker
34
+ }
35
+
36
+ install_or_update() {
37
+ local action="$1" repo_root backup_path="" installed_sha
38
+ shift
39
+ omd_module_reject_unknown_flags "$@" || return
40
+
41
+ if status && ! managed; then
42
+ omd_module_external_installation "${component}"
43
+ return 0
44
+ fi
45
+ if omd_module_path_exists "${bin_path}" && ! managed; then
46
+ omd_module_info error "refusing to overwrite unmanaged path: ${bin_path}"
47
+ return 1
48
+ fi
49
+ if omd_module_dry_run "$@"; then
50
+ omd_module_info plan "${action} official Gitee CLI binary at ${bin_path}"
51
+ return 0
52
+ fi
53
+
54
+ repo_root="$(omd_module_repo_root)"
55
+ if [[ -f "${bin_path}" ]]; then
56
+ backup_path="$(mktemp "$(dirname "${bin_path}")/.gitee.backup.XXXXXXXX")"
57
+ cp -p "${bin_path}" "${backup_path}"
58
+ fi
59
+
60
+ if ! OHMYDEVPOD_BIN_DIR="$(omd_module_bin_dir)" \
61
+ bash "${repo_root}/build/install-gitee-cli.sh"; then
62
+ [[ -z "${backup_path}" ]] || rm -f "${backup_path}"
63
+ return 1
64
+ fi
65
+
66
+ if ! installed_sha="$(omd_module_sha256_file "${bin_path}")" ||
67
+ ! omd_module_mark_managed \
68
+ "${component}" \
69
+ binary \
70
+ "${bin_path}" \
71
+ "binary_sha256=${installed_sha}"; then
72
+ if [[ -n "${backup_path}" ]]; then
73
+ mv -f "${backup_path}" "${bin_path}"
74
+ else
75
+ rm -f "${bin_path}"
76
+ fi
77
+ return 1
78
+ fi
79
+
80
+ [[ -z "${backup_path}" ]] || rm -f "${backup_path}"
81
+ }
82
+
83
+ uninstall() {
84
+ omd_module_require_managed_uninstall "${component}" managed "$@" || return
85
+ if omd_module_dry_run "$@"; then
86
+ omd_module_info plan "remove managed Gitee CLI binary ${bin_path}; preserve configuration and authentication"
87
+ return 0
88
+ fi
89
+
90
+ rm -f "${bin_path}"
91
+ omd_module_unmark_managed "${component}"
92
+ }
93
+
94
+ case "${1:-}" in
95
+ status) status ;;
96
+ managed) managed ;;
97
+ install) shift; install_or_update install "$@" ;;
98
+ update) shift; install_or_update update "$@" ;;
99
+ uninstall) shift; uninstall "$@" ;;
100
+ *) omd_module_unknown_action "${1:-}" ;;
101
+ esac