just-bashit 0.2.0__py3-none-any.whl

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.
just_bashit/inspect.sh ADDED
@@ -0,0 +1,220 @@
1
+ #!/bin/bash
2
+ # ############################################################################
3
+ # EXECUTABLE: inspect.sh #
4
+ # PACKAGE: just-bashit version 0.2.0 #
5
+ # ############################################################################
6
+ # Query installed versions of system deps from a TOML deps file, plus system #
7
+ # and compiler info. Output is valid TOML (suitable as a lock file). #
8
+ # ############################################################################
9
+ set -euo pipefail
10
+ IFS=$'\n\t'
11
+
12
+ _SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+ # shellcheck source=/dev/null
14
+ source "${_SCRIPT_DIR}/toml.sh"
15
+ # shellcheck source=/dev/null
16
+ source "${_SCRIPT_DIR}/pkg.sh"
17
+
18
+ VERBOSE=0
19
+ WRITE_LOCK=0
20
+ LOCK_FILE="jb.versions"
21
+ SECTION_OVERRIDE=""
22
+ GROUPS_STR=""
23
+ GROUPS_EXPLICIT=0
24
+ DEPS_FILE=""
25
+
26
+ read -r -d '' HELP <<-'EOF' || true
27
+ Usage: inspect.sh [OPTIONS] [DEPS_FILE]
28
+
29
+ Query installed versions of system packages listed in a TOML deps file,
30
+ together with system and compiler information. Output is valid TOML,
31
+ suitable for committing as jb.versions to record the build environment.
32
+ Input resolution: DEPS_FILE arg > jb-deps.toml > jb.toml > stdin.
33
+
34
+ Output sections:
35
+ [system] os, kernel, arch, glibc
36
+ [compiler] gcc, clang, rustc, python3, cmake (any found on PATH)
37
+ [group.pm] installed version of each package in the deps file;
38
+ cmd sections are noted but versions are not queried
39
+
40
+ jb.versions records what IS installed — it does not pin versions or
41
+ affect what install-deps installs.
42
+
43
+ Options:
44
+ -h / --help Show this message and exit.
45
+ -v / --verbose Print resolved section and groups to stderr.
46
+ -w / --write [FILE] Also write output to FILE (default: jb.versions).
47
+ -s / --section SECTION Override auto-detected package manager.
48
+ -g / --groups GROUP Comma-separated groups to inspect (default: all
49
+ groups in deps file, or [tools.inspect].groups).
50
+
51
+ Arguments:
52
+ DEPS_FILE Path to TOML deps file. Omit to auto-discover.
53
+ EOF
54
+
55
+ # ---------------------------------------------------------------------------
56
+ # Argument parsing
57
+ # ---------------------------------------------------------------------------
58
+ while [[ $# -gt 0 ]]; do
59
+ case "$1" in
60
+ -h | --help)
61
+ echo "${HELP}"
62
+ exit 0
63
+ ;;
64
+ -v | --verbose)
65
+ VERBOSE=1
66
+ shift
67
+ ;;
68
+ -w | --write)
69
+ WRITE_LOCK=1
70
+ if [[ $# -gt 1 && "${2}" != -* ]]; then
71
+ LOCK_FILE="${2}"
72
+ shift 2
73
+ else
74
+ shift
75
+ fi
76
+ ;;
77
+ -s | --section)
78
+ SECTION_OVERRIDE="${2:?Option $1 requires an argument.}"
79
+ shift 2
80
+ ;;
81
+ -g | --groups)
82
+ GROUPS_STR="${2:?Option $1 requires an argument.}"
83
+ GROUPS_EXPLICIT=1
84
+ shift 2
85
+ ;;
86
+ -*)
87
+ echo "Invalid option: $1"
88
+ echo "${HELP}"
89
+ exit 1
90
+ ;;
91
+ *)
92
+ DEPS_FILE="$1"
93
+ shift
94
+ ;;
95
+ esac
96
+ done
97
+
98
+ _log() { [[ ${VERBOSE} -eq 1 ]] && echo "$*" >&2 || true; }
99
+
100
+ # ---------------------------------------------------------------------------
101
+ # _tool_version: first line of a tool's --version output; empty if missing.
102
+ # ---------------------------------------------------------------------------
103
+ _tool_version() {
104
+ local cmd="$1"
105
+ shift
106
+ command -v "${cmd}" >/dev/null 2>&1 || return 0
107
+ "${cmd}" "$@" 2>/dev/null | head -1 || true
108
+ }
109
+
110
+ # ---------------------------------------------------------------------------
111
+ # _do_inspect: emit all TOML output to stdout.
112
+ # ---------------------------------------------------------------------------
113
+ _do_inspect() {
114
+ printf '# jb.versions — generated by jbx inspect %s\n' \
115
+ "$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
116
+ printf '# regenerate: jbx inspect -w\n'
117
+ printf '\n'
118
+
119
+ # [system] ----------------------------------------------------------------
120
+ printf '[system]\n'
121
+ local _os_name="" _os_version="" _glibc=""
122
+ if [ -f /etc/os-release ]; then
123
+ # shellcheck source=/dev/null
124
+ _os_name=$(. /etc/os-release && printf '%s' "${NAME:-}")
125
+ _os_version=$(. /etc/os-release &&
126
+ printf '%s' "${VERSION_ID:-${BUILD_ID:-rolling}}")
127
+ fi
128
+ printf 'os = "%s (%s)"\n' "${_os_name:-unknown}" "${_os_version:-unknown}"
129
+ printf 'kernel = "%s"\n' "$(uname -r)"
130
+ printf 'arch = "%s"\n' "$(uname -m)"
131
+ _glibc=$(getconf GNU_LIBC_VERSION 2>/dev/null ||
132
+ ldd --version 2>/dev/null | head -1 || true)
133
+ [ -n "${_glibc}" ] && printf 'glibc = "%s"\n' "${_glibc}"
134
+ printf '\n'
135
+
136
+ # [compiler] --------------------------------------------------------------
137
+ printf '[compiler]\n'
138
+ local _v
139
+ _v=$(_tool_version gcc --version)
140
+ [ -n "${_v}" ] && printf 'gcc = "%s"\n' "${_v}"
141
+ _v=$(_tool_version clang --version)
142
+ [ -n "${_v}" ] && printf 'clang = "%s"\n' "${_v}"
143
+ _v=$(_tool_version rustc --version)
144
+ [ -n "${_v}" ] && printf 'rustc = "%s"\n' "${_v}"
145
+ _v=$(_tool_version python3 --version)
146
+ [ -n "${_v}" ] && printf 'python3 = "%s"\n' "${_v}"
147
+ _v=$(_tool_version cmake --version)
148
+ [ -n "${_v}" ] && printf 'cmake = "%s"\n' "${_v}"
149
+ printf '\n'
150
+
151
+ # [group.section] for each group ------------------------------------------
152
+ local _group _pkg _ver
153
+ while IFS= read -r _group; do
154
+ [ -z "${_group}" ] && continue
155
+
156
+ # cmd sections: note the command; no versions to query.
157
+ local _cmd=()
158
+ while IFS= read -r _c; do _cmd+=("${_c}"); done \
159
+ < <(printf '%s\n' "${CONTENT}" | toml_get_cmd "${_group}" "${SECTION}")
160
+ if [ "${#_cmd[@]}" -gt 0 ]; then
161
+ printf '[%s.%s]\n' "${_group}" "${SECTION}"
162
+ (
163
+ IFS=' '
164
+ printf '# cmd = %s\n' "${_cmd[*]}"
165
+ )
166
+ printf '# versions not queried for custom cmd sections\n'
167
+ printf '\n'
168
+ continue
169
+ fi
170
+
171
+ local _pkgs=()
172
+ while IFS= read -r _p; do _pkgs+=("${_p}"); done \
173
+ < <(printf '%s\n' "${CONTENT}" | toml_get_packages "${_group}" "${SECTION}")
174
+ [ "${#_pkgs[@]}" -eq 0 ] && continue
175
+
176
+ printf '[%s.%s]\n' "${_group}" "${SECTION}"
177
+ for _pkg in "${_pkgs[@]}"; do
178
+ _ver=$(get-pkg-version "${SECTION}" "${_pkg}")
179
+ if [ -n "${_ver}" ]; then
180
+ printf '%s = "%s"\n' "${_pkg}" "${_ver}"
181
+ else
182
+ printf '# %s = not installed\n' "${_pkg}"
183
+ fi
184
+ done
185
+ printf '\n'
186
+ done < <(tr ',' '\n' <<<"${GROUPS_STR}")
187
+ }
188
+
189
+ # ---------------------------------------------------------------------------
190
+ # Main
191
+ # ---------------------------------------------------------------------------
192
+ if [ -n "${DEPS_FILE}" ]; then
193
+ CONTENT=$(cat "${DEPS_FILE}")
194
+ elif [ -f "jb-deps.toml" ]; then
195
+ CONTENT=$(cat "jb-deps.toml")
196
+ elif [ -f "jb.toml" ]; then
197
+ CONTENT=$(cat "jb.toml")
198
+ else
199
+ CONTENT=$(cat)
200
+ fi
201
+
202
+ if [[ ${GROUPS_EXPLICIT} -eq 0 ]]; then
203
+ _toml_g=$(printf '%s\n' "${CONTENT}" | toml_get_tool_groups "inspect")
204
+ if [[ -n "${_toml_g}" ]]; then
205
+ GROUPS_STR="${_toml_g}"
206
+ else
207
+ GROUPS_STR=$(printf '%s\n' "${CONTENT}" | toml_discover_groups)
208
+ fi
209
+ fi
210
+
211
+ SECTION="${SECTION_OVERRIDE:-$(get-pkg-mgr)}"
212
+ _log "section: ${SECTION}"
213
+ _log "groups: ${GROUPS_STR}"
214
+
215
+ if [[ ${WRITE_LOCK} -eq 1 ]]; then
216
+ _do_inspect | tee "${LOCK_FILE}"
217
+ echo "wrote ${LOCK_FILE}" >&2
218
+ else
219
+ _do_inspect
220
+ fi
@@ -0,0 +1,300 @@
1
+ #!/bin/bash
2
+ # ############################################################################
3
+ # EXECUTABLE: install-deps.sh #
4
+ # PACKAGE: just-bashit version 0.2.0 #
5
+ # ############################################################################
6
+ set -euo pipefail
7
+ IFS=$'\n\t'
8
+
9
+ _SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ # shellcheck source=/dev/null
11
+ source "${_SCRIPT_DIR}/toml.sh"
12
+ # shellcheck source=/dev/null
13
+ source "${_SCRIPT_DIR}/pkg.sh"
14
+
15
+ DRY_RUN=0
16
+ VERBOSE=0
17
+ SECTION_OVERRIDE=""
18
+ GROUPS_STR=""
19
+ GROUPS_EXPLICIT=0
20
+ TEMPLATE=0
21
+ TEMPLATE_PATH="-"
22
+
23
+ read -r -d '' HELP <<-'EOF' || true
24
+ Usage: install-deps.sh [OPTIONS] [DEPS_FILE]
25
+
26
+ Install system packages for the detected OS from a declarative TOML file.
27
+ Auto-detects the package manager from the OS. By default installs ALL
28
+ groups defined in the file.
29
+ Input resolution: DEPS_FILE arg > jb-deps.toml > jb.toml > stdin.
30
+
31
+ Section format — standard install:
32
+
33
+ [GROUP.PACKAGE_MANAGER]
34
+ packages = ["pkg1", "pkg2"]
35
+
36
+ Section format — custom command (escape hatch, overrides packages):
37
+
38
+ [GROUP.PACKAGE_MANAGER]
39
+ cmd = ["sudo", "apt-get", "install", "-y", "pkg=1.2.3"]
40
+
41
+ Examples:
42
+
43
+ [runtime.pacman]
44
+ packages = ["zeromq", "fftw"]
45
+
46
+ [dev.apt]
47
+ packages = ["build-essential", "cmake"]
48
+
49
+ [pinned.apt]
50
+ cmd = ["apt-get", "install", "-y", "libzmq3-dev=4.3.4-1"]
51
+
52
+ Supported package managers: apt, pacman, brew, dnf, zypper, apk, msys2.
53
+
54
+ Default groups: all groups found in the file. To restrict defaults,
55
+ set groups = [...] under [tools.install-deps] in jb.toml.
56
+
57
+ Options:
58
+ -h / --help Show this message and exit.
59
+ -n / --dry-run Print commands without executing them.
60
+ -v / --verbose Print section, groups, and packages before acting.
61
+ -s / --section SECTION Override auto-detected package manager.
62
+ -g / --groups GROUP Comma-separated groups to install (overrides all
63
+ defaults; e.g. -g runtime or -g runtime,dev).
64
+ --template [PATH] Write a scaffold deps.toml to PATH (default: stdout).
65
+
66
+ Arguments:
67
+ DEPS_FILE Path to TOML file. Omit to auto-discover jb-deps.toml or jb.toml.
68
+ EOF
69
+
70
+ # ---------------------------------------------------------------------------
71
+ # Argument parsing — manual loop to support both short and long options.
72
+ # ---------------------------------------------------------------------------
73
+ DEPS_FILE=""
74
+ while [[ $# -gt 0 ]]; do
75
+ case "$1" in
76
+ -h | --help)
77
+ echo "${HELP}"
78
+ exit 0
79
+ ;;
80
+ -n | --dry-run)
81
+ DRY_RUN=1
82
+ shift
83
+ ;;
84
+ -v | --verbose)
85
+ VERBOSE=1
86
+ shift
87
+ ;;
88
+ -s | --section)
89
+ SECTION_OVERRIDE="${2:?Option $1 requires an argument.}"
90
+ shift 2
91
+ ;;
92
+ -g | --groups)
93
+ GROUPS_STR="${2:?Option $1 requires an argument.}"
94
+ GROUPS_EXPLICIT=1
95
+ shift 2
96
+ ;;
97
+ --template)
98
+ TEMPLATE=1
99
+ if [[ $# -gt 1 && "${2}" != -* ]]; then
100
+ TEMPLATE_PATH="${2}"
101
+ shift 2
102
+ else
103
+ TEMPLATE_PATH="-"
104
+ shift
105
+ fi
106
+ ;;
107
+ -*)
108
+ echo "Invalid option: $1"
109
+ echo "${HELP}"
110
+ exit 1
111
+ ;;
112
+ *)
113
+ DEPS_FILE="$1"
114
+ shift
115
+ ;;
116
+ esac
117
+ done
118
+
119
+ # ---------------------------------------------------------------------------
120
+ # _log: print to stderr when verbose is on.
121
+ # ---------------------------------------------------------------------------
122
+ _log() { [[ ${VERBOSE} -eq 1 ]] && echo "$*" >&2 || true; }
123
+
124
+ # ---------------------------------------------------------------------------
125
+ # _template: emit a scaffold deps.toml to stdout or a file.
126
+ # ---------------------------------------------------------------------------
127
+ _template() {
128
+ local dest="${1}"
129
+ if [[ "${dest}" == "-" ]]; then
130
+ cat "${_SCRIPT_DIR}/template.toml"
131
+ else
132
+ cat "${_SCRIPT_DIR}/template.toml" >"${dest}"
133
+ echo "wrote ${dest}" >&2
134
+ fi
135
+ }
136
+
137
+ # ---------------------------------------------------------------------------
138
+ # _do_install: run or print the install command for the detected section.
139
+ # ---------------------------------------------------------------------------
140
+ _do_install() {
141
+ local section="$1"
142
+ shift
143
+ case "${section}" in
144
+ apt)
145
+ if [ "${DRY_RUN}" -eq 1 ]; then
146
+ echo "sudo apt-get update"
147
+ (
148
+ IFS=' '
149
+ echo "sudo apt-get install -y --no-install-recommends $*"
150
+ )
151
+ return
152
+ fi
153
+ sudo apt-get update
154
+ sudo apt-get install -y --no-install-recommends "$@"
155
+ ;;
156
+ pacman)
157
+ if [ "${DRY_RUN}" -eq 1 ]; then
158
+ (
159
+ IFS=' '
160
+ echo "sudo pacman -Sy --needed --noconfirm $*"
161
+ )
162
+ return
163
+ fi
164
+ sudo pacman -Sy --needed --noconfirm "$@"
165
+ ;;
166
+ brew)
167
+ if [ "${DRY_RUN}" -eq 1 ]; then
168
+ (
169
+ IFS=' '
170
+ echo "brew install $*"
171
+ )
172
+ return
173
+ fi
174
+ brew install "$@"
175
+ ;;
176
+ dnf)
177
+ if [ "${DRY_RUN}" -eq 1 ]; then
178
+ (
179
+ IFS=' '
180
+ echo "sudo dnf install -y $*"
181
+ )
182
+ return
183
+ fi
184
+ sudo dnf install -y "$@"
185
+ ;;
186
+ zypper)
187
+ if [ "${DRY_RUN}" -eq 1 ]; then
188
+ (
189
+ IFS=' '
190
+ echo "sudo zypper install -y $*"
191
+ )
192
+ return
193
+ fi
194
+ sudo zypper install -y "$@"
195
+ ;;
196
+ apk)
197
+ if [ "${DRY_RUN}" -eq 1 ]; then
198
+ (
199
+ IFS=' '
200
+ echo "sudo apk add $*"
201
+ )
202
+ return
203
+ fi
204
+ sudo apk add "$@"
205
+ ;;
206
+ msys2)
207
+ # msys2 is Windows — always print instructions, never run.
208
+ echo "Windows/MSYS2: open a UCRT64 shell and run:"
209
+ (
210
+ IFS=' '
211
+ echo " pacman -S $*"
212
+ )
213
+ exit 0
214
+ ;;
215
+ *)
216
+ echo "error: unknown section '${section}'" >&2
217
+ exit 1
218
+ ;;
219
+ esac
220
+ }
221
+
222
+ # ---------------------------------------------------------------------------
223
+ # Main
224
+ # ---------------------------------------------------------------------------
225
+
226
+ if [[ ${TEMPLATE} -eq 1 ]]; then
227
+ _template "${TEMPLATE_PATH}"
228
+ exit 0
229
+ fi
230
+
231
+ # Slurp deps content: explicit file > jb-deps.toml > jb.toml > stdin.
232
+ if [ -n "${DEPS_FILE}" ]; then
233
+ CONTENT=$(cat "${DEPS_FILE}")
234
+ elif [ -f "jb-deps.toml" ]; then
235
+ CONTENT=$(cat "jb-deps.toml")
236
+ elif [ -f "jb.toml" ]; then
237
+ CONTENT=$(cat "jb.toml")
238
+ else
239
+ CONTENT=$(cat)
240
+ fi
241
+
242
+ # Resolve groups: explicit -g > [tools.install-deps].groups in toml > all.
243
+ if [[ ${GROUPS_EXPLICIT} -eq 0 ]]; then
244
+ _toml_g=$(printf '%s\n' "${CONTENT}" | toml_get_tool_groups "install-deps")
245
+ if [[ -n "${_toml_g}" ]]; then
246
+ GROUPS_STR="${_toml_g}"
247
+ else
248
+ GROUPS_STR=$(printf '%s\n' "${CONTENT}" | toml_discover_groups)
249
+ fi
250
+ fi
251
+
252
+ SECTION="${SECTION_OVERRIDE:-$(get-pkg-mgr)}"
253
+
254
+ _log "section: ${SECTION}"
255
+ _log "groups: ${GROUPS_STR}"
256
+
257
+ # Process each group: cmd wins over packages; each runs independently.
258
+ _any=0
259
+ while IFS= read -r _group; do
260
+ [ -z "${_group}" ] && continue
261
+
262
+ _cmd=()
263
+ while IFS= read -r _c; do _cmd+=("${_c}"); done \
264
+ < <(printf '%s\n' "${CONTENT}" | toml_get_cmd "${_group}" "${SECTION}")
265
+
266
+ if [ "${#_cmd[@]}" -gt 0 ]; then
267
+ _any=1
268
+ (
269
+ IFS=' '
270
+ _log "cmd: ${_cmd[*]}"
271
+ )
272
+ if [ "${DRY_RUN}" -eq 1 ]; then
273
+ (
274
+ IFS=' '
275
+ echo "${_cmd[*]}"
276
+ )
277
+ else
278
+ "${_cmd[@]}"
279
+ fi
280
+ continue
281
+ fi
282
+
283
+ _pkgs=()
284
+ while IFS= read -r _p; do _pkgs+=("${_p}"); done \
285
+ < <(printf '%s\n' "${CONTENT}" | toml_get_packages "${_group}" "${SECTION}")
286
+ [ "${#_pkgs[@]}" -eq 0 ] && continue
287
+ _any=1
288
+ (
289
+ IFS=' '
290
+ _log "packages: ${_pkgs[*]}"
291
+ )
292
+ _do_install "${SECTION}" "${_pkgs[@]}"
293
+ done < <(tr ',' '\n' <<<"${GROUPS_STR}")
294
+ unset _group _cmd _pkgs _p _c
295
+
296
+ if [ "${_any}" -eq 0 ]; then
297
+ echo "error: no packages or cmd found for group(s) '${GROUPS_STR}'" \
298
+ "section '${SECTION}' in deps file" >&2
299
+ exit 1
300
+ fi