oh-my-devpod 0.14.2 → 0.14.3

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.
@@ -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
@@ -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="yq"
7
+ formula="yq"
8
+ command_name="yq"
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