Compare commits

..

No commits in common. "86d07730bc2e5e7652937b130b8d94e12943dec3" and "58192fa9f8e458164abb3155af2fcc57986db36f" have entirely different histories.

2 changed files with 368 additions and 368 deletions

55
spcd.sh
View file

@ -1,30 +1,31 @@
#! /usr/bin/env sh
gource \
--auto-skip-seconds 0.25 \
--date-format "%Y / %m / %d ⋅ %H : %M : %S" \
--disable-input \
--font-scale 2.5 \
--frameless \
--hide mouse,usernames \
--highlight-dirs \
--key \
--multi-sampling \
--output-framerate 60 \
--output-ppm-stream - \
--seconds-per-day 0.6 \
--stop-at-end \
--viewport "1920x1080" |
ffmpeg \
-codec:v ppm \
-format image2pipe \
-framerate 120 \
-i - \
-codec:v libx264 \
-preset veryslow \
-qp 28 \
-movflags \
+faststart \
-pix_fmt yuv420p \
-y \
spcd.mp4
--auto-skip-seconds 0.25 \
--date-format "%Y / %m / %d ⋅ %H : %M : %S" \
--disable-input \
--font-scale 2.5 \
--frameless \
--hide mouse,usernames \
--highlight-dirs \
--key \
--multi-sampling \
--output-framerate 60 \
--output-ppm-stream - \
--seconds-per-day 0.6 \
--stop-at-end \
--viewport "1920x1080" \
| \
ffmpeg \
-codec:v ppm \
-format image2pipe \
-framerate 120 \
-i - \
-codec:v libx264 \
-preset veryslow \
-qp 28 \
-movflags \
+faststart \
-pix_fmt yuv420p \
-y \
spcd.mp4

View file

@ -211,6 +211,54 @@ _spcd_txt_pick() {
# │ p = public │
# ╰────────────╯
spcd_ca() {
local grep="\(After\|Before\|Issuer\|Signature Algorithm\|Subject:\)"
local index name value
local root="${2}"
while true; do
index=$((index + 1))
name="SPCD_CA_${index}"
eval "value=\"\${${name}}\""
[ -n "${value}" ] || break
case "${1}" in
"list")
echo "${name} ="
echo "${value}" |
openssl x509 -noout -text |
grep "${grep}"
;;
"write")
spcd_os_write "${root}/${index}.crt" "${value}"
;;
*) ;;
esac
done
}
spcd_dns() {
local index name text value
while true; do
index=$((index + 1))
name="SPCD_DNS_${index}"
eval "value=\"\${${name}}\""
[ -n "${value}" ] || break
case "${1}" in
"list")
spcd_os_printenv "${name}"
;;
"write")
text="${text}\
nameserver ${value}
"
;;
*) ;;
esac
done
if [ "${1}" = "write" ]; then
spcd_os_write "/etc/resolv.conf" "${text}"
fi
}
spcd_run() {
if [ -n "${1}" ]; then
_spcd_frame_open "${@}"
@ -377,8 +425,8 @@ SPCD_PM_ZYPPER="zypper"
# ╰───┴───────────╯
spcd_step__environment_print() {
spcd_f_ca "list"
spcd_f_dns "list"
spcd_ca "list"
spcd_dns "list"
set -- \
"GIT_RWX" \
"GIT_SPCD" \
@ -737,166 +785,61 @@ ${SPCD_PYTHON_VENV}/lib/${SPCD_PYTHON_COMMAND}/site-packages"
spcd_os_printenv "SPCD_DL"
}
spcd_step__environment_list_workspace() {
spcd_step "List workspace"
spcd_os_ls "$(realpath .)"
}
# ╭──────────────╮
# │ f = function │
# ╰──────────────╯
spcd_f_dns() {
local index name text value
while true; do
index=$((index + 1))
name="SPCD_DNS_${index}"
eval "value=\"\${${name}}\""
[ -n "${value}" ] || break
case "${1}" in
"list")
spcd_os_printenv "${name}"
;;
"write")
text="${text}\
nameserver ${value}
"
;;
*) ;;
esac
done
if [ "${1}" = "write" ]; then
spcd_os_write "/etc/resolv.conf" "${text}"
spcd_git_clone() {
if [ -n "${1}" ]; then
local name path url
name="$(basename "${1}")"
path="${SPCD_DL}/${name}"
url="$(spcd_git_url "${1}")"
git clone "${url}" "${path}"
echo "${path}"
fi
}
spcd_f_pkg() {
spcd_step_in "OS packages"
local file
# epel
spcd_step "EPEL"
case "${SPCD_OS_ID}" in
"${SPCD_OS_ALMA}" | "${SPCD_OS_ROCKY}")
spcd_f_pm_pkg_install "epel-release"
case "${SPCD_OS_VERSION}" in
"9")
set -- \
"-testing" \
""
;;
"8")
set -- \
"-modular" \
"-testing-modular" \
"-testing" \
""
;;
*) ;;
spcd_git_url() {
if [ -n "${1}" ]; then
case "${1}" in
http*) echo "${1}" ;;
*/*) echo "${SPCD_PROJECT_ROOT}/${1}" ;;
*) echo "${SPCD_PROJECT_ROOT}/${SPCD_PROJECT_PATH}/${1}" ;;
esac
for file in "${@}"; do
spcd_os_sed "/etc/yum.repos.d/epel${file}.repo" \
"|^metalink|#metalink|" \
"|https://download.example/pub/epel|${SPCD_URL_EPEL}|" \
"|^#baseurl|baseurl|"
done
file="/etc/yum.repos.d/epel-cisco-openh264.repo"
if [ -f "${file}" ]; then
spcd_os_sed "${file}" \
"|^enabled=1|enabled=0|"
fi
;;
*) ;;
esac
# graphviz
spcd_step "GraphViz"
spcd_f_pm_pkg_install "graphviz"
# openssh
spcd_step "OpenSSH"
case "${SPCD_PM}" in
"${SPCD_PM_APK}" | "${SPCD_PM_APT}")
spcd_f_pm_pkg_install "openssh-client"
;;
"${SPCD_PM_DNF}" | "${SPCD_PM_ZYPPER}")
spcd_f_pm_pkg_install "openssh-clients"
;;
"${SPCD_PM_PACMAN}") spcd_f_pm_pkg_install "openssh" ;;
*) ;;
esac
# plantuml
spcd_step "PlantUML"
spcd_f_pm_pkg_install "plantuml"
# rsync
spcd_step "Rsync"
spcd_f_pm_pkg_install "rsync"
# shell check
spcd_step "ShellCheck"
case "${SPCD_PM}" in
"${SPCD_PM_DNF}" | "${SPCD_PM_ZYPPER}")
spcd_f_pm_pkg_install "ShellCheck"
;;
*) spcd_f_pm_pkg_install "shellcheck" ;;
esac
# shfmt
spcd_step "ShellFormat"
case "${SPCD_OS_ID}" in
"${SPCD_OS_ALMA}" | "${SPCD_OS_ROCKY}") ;;
"${SPCD_OS_DEBIAN}")
case "${SPCD_OS_VERSION}" in
"bullseye") ;;
*) spcd_f_pm_pkg_install "shfmt" ;;
esac
;;
*) spcd_f_pm_pkg_install "shfmt" ;;
esac
spcd_step_out
}
spcd_python_ln() {
local command="${1}"
if [ -n "${command}" ]; then
echo "${SPCD_PYTHON_ALIAS}${command}"
ln -f -s "${command}" \
"/usr/bin/${SPCD_PYTHON_ALIAS}"
fi
}
spcd_python_pip() {
if [ -n "${1}" ]; then
local name path target
name="$(basename "${1}")"
path="$(spcd_git_clone "${1}")"
path="${path}/${name}"
target="${SPCD_PYTHON_VENV_PACKAGES}"
cp --recursive "${path}" "${target}"
echo "${target}/${name}"
fi
}
# ╭───┬──────────────────────────────╮
# │ f │ ca = certificate authorities │
# ╰───┴──────────────────────────────╯
spcd_f_ca() {
case "${1}" in
"list")
local grep="\(After\|Before\|Issuer\|Signature Algorithm\|Subject:\)"
;;
"write")
local root
case "${SPCD_OS_ID}" in
"${SPCD_OS_ALMA}" | "${SPCD_OS_FEDORA}" | "${SPCD_OS_ROCKY}")
root="/etc/pki/ca-trust/source/anchors"
;;
"${SPCD_OS_ALPINE}" | "${SPCD_OS_DEBIAN}" | "${SPCD_OS_UBUNTU}")
root="/usr/local/share/ca-certificates"
;;
"${SPCD_OS_ARCH}")
root="/etc/ca-certificates/trust-source/anchors"
;;
"${SPCD_OS_OPENSUSE}")
root="/etc/pki/trust/anchors"
;;
*) ;;
esac
spcd_os_mkdir "${root}"
;;
*) ;;
esac
local index name value
while true; do
index=$((index + 1))
name="SPCD_CA_${index}"
eval "value=\"\${${name}}\""
[ -n "${value}" ] || break
case "${1}" in
"list")
echo "${name} ="
echo "${value}" |
openssl x509 -noout -text |
grep "${grep}"
;;
"write")
spcd_os_write "${root}/${index}.crt" "${value}"
;;
*) ;;
esac
done
}
spcd_f_ca_install() {
spcd_step "Install package"
spcd_f_pm_pkg_install "ca-certificates"
@ -921,57 +864,40 @@ spcd_f_ca_update() {
esac
}
# ╭───┬───────────────────╮
# │ f │ env = environment │
# ╰───┴───────────────────╯
spcd_f_env_workspace() {
spcd_os_ls "$(realpath .)"
}
# ╭───┬─────╮
# │ f │ git │
# ╰───┴─────╯
spcd_f_git_clone() {
if [ -n "${1}" ]; then
local name path url
name="$(basename "${1}")"
path="${SPCD_DL}/${name}"
url="$(spcd_f_git_url "${1}")"
git clone "${url}" "${path}"
echo "${path}"
fi
}
spcd_f_git_url() {
if [ -n "${1}" ]; then
case "${1}" in
http*) echo "${1}" ;;
*/*) echo "${SPCD_PROJECT_ROOT}/${1}" ;;
*) echo "${SPCD_PROJECT_ROOT}/${SPCD_PROJECT_PATH}/${1}" ;;
spcd_f_ca_write() {
spcd_step "Write certificates"
local root
case "${SPCD_OS_ID}" in
"${SPCD_OS_ALMA}" | "${SPCD_OS_FEDORA}" | "${SPCD_OS_ROCKY}")
root="/etc/pki/ca-trust/source/anchors"
;;
"${SPCD_OS_ALPINE}" | "${SPCD_OS_DEBIAN}" | "${SPCD_OS_UBUNTU}")
root="/usr/local/share/ca-certificates"
;;
"${SPCD_OS_ARCH}")
root="/etc/ca-certificates/trust-source/anchors"
;;
"${SPCD_OS_OPENSUSE}")
root="/etc/pki/trust/anchors"
;;
*) ;;
esac
fi
}
# ╭───┬───────────────╮
# │ f │ pkg = package │
# ╰───┴───────────────╯
spcd_f_pkg_dos2unix() {
spcd_step "Install dos2unix"
spcd_f_pm_pkg_install "dos2unix"
}
spcd_f_pkg_git() {
spcd_step "Install Git"
spcd_f_pm_pkg_install "git"
spcd_os_mkdir "${root}"
spcd_ca "write" "${root}"
}
# ╭───┬──────────────────────╮
# │ f │ pm = package manager │
# ╰───┴──────────────────────╯
spcd_f_pm_install() {
spcd_step "Install tools"
case "${SPCD_PM}" in
"${SPCD_PM_APT}") spcd_f_pm_pkg_install "apt-utils" ;;
*) ;;
esac
}
# ╭───┬────┬───────╮
# │ f │ pm │ https │
# ╰───┴────┴───────╯
@ -1041,27 +967,15 @@ spcd_f_pm_pkg_clean() {
}
spcd_f_pm_pkg_install() {
if [ -n "${1}" ]; then
local name
for name in "${@}"; do
case "${SPCD_PM}" in
"${SPCD_PM_APK}") spcd_run apk add "${1}" ;;
"${SPCD_PM_APT}") spcd_run apt-get install --assume-yes "${1}" ;;
"${SPCD_PM_DNF}") spcd_run dnf install --assumeyes "${1}" ;;
"${SPCD_PM_PACMAN}") spcd_run pacman --sync --noconfirm "${1}" ;;
"${SPCD_PM_ZYPPER}")
spcd_run zypper --non-interactive install "${1}"
;;
"${SPCD_PM_ZYPPER}") spcd_run zypper --non-interactive install "${1}" ;;
*) ;;
esac
spcd_f_pm_pkg_clean
done
else
case "${SPCD_PM}" in
"${SPCD_PM_APT}") spcd_f_pm_pkg_install "apt-utils" ;;
*) ;;
esac
fi
}
spcd_f_pm_pkg_query() {
@ -1099,117 +1013,6 @@ spcd_f_pm_pkg_upgrade() {
esac
}
# ╭───┬─────────────╮
# │ f │ py = python │
# ╰───┴─────────────╯
spcd_f_py_clone() {
if [ -n "${1}" ]; then
local name path target
name="$(basename "${1}")"
path="$(spcd_f_git_clone "${1}")"
path="${path}/${name}"
target="${SPCD_PYTHON_VENV_PACKAGES}"
cp --recursive "${path}" "${target}"
echo "${target}/${name}"
fi
}
spcd_f_py_download() {
spcd_step_in "Modules"
local target path script check
target="${SPCD_PYTHON_VENV_PACKAGES}"
spcd_step "List"
spcd_os_ls "${target}"
spcd_step "Main"
path="$(spcd_f_py_clone "${SPCD_GIT_SPCD}")"
# check matching of file and variable
spcd_step "Check"
script="${path}/bootstrap.sh"
ls -l "${script}"
check="${script}.${_SPCD_CMD_SUM}"
"${_SPCD_CMD_SUM}" "${script}" >"${check}"
printf "%s" "${SPCD}" >"${script}"
ls -l "${script}"
dos2unix "${script}"
ls -l "${script}"
"${_SPCD_CMD_SUM}" -c "${check}" || spcd_error_ci "SPCD"
spcd_step "Root"
spcd_f_py_clone "${SPCD_GIT_RWX}"
spcd_step "List"
spcd_os_ls "${target}"
spcd_step_out
}
spcd_f_py_install() {
spcd_step "Install package"
spcd_f_pm_pkg_install "${SPCD_PYTHON_PACKAGE}"
spcd_step "Link alias to command"
spcd_f_py_link "${SPCD_PYTHON_COMMAND}"
# venv
spcd_step_in "Virtual environment"
spcd_step "Install package"
case "${SPCD_OS_ID}" in
"${SPCD_OS_DEBIAN}" | "${SPCD_OS_UBUNTU}")
spcd_f_pm_pkg_install "python3-venv"
;;
*) ;;
esac
spcd_step "Configure PIP"
spcd_os_write "/etc/pip.conf" "\
[global]
index-url = ${SPCD_URL_PYTHON}/simple
"
spcd_step "Create"
"${SPCD_PYTHON_ALIAS}" -m "venv" "${SPCD_PYTHON_VENV}"
spcd_step "Activate"
export PATH="${SPCD_PYTHON_VENV_BINARIES}:${PATH}"
export VIRTUAL_ENV="${SPCD_PYTHON_VENV}"
spcd_step_out
}
spcd_f_py_link() {
local command="${1}"
if [ -n "${command}" ]; then
echo "${SPCD_PYTHON_ALIAS}${command}"
ln -f -s "${command}" \
"/usr/bin/${SPCD_PYTHON_ALIAS}"
fi
}
spcd_f_py_save() {
spcd_step "Save"
local variable value text index root
for variable in \
OS_ID OS_VERSION \
PROJECT_ROOT PROJECT_PATH PROJECT_NAME \
PYTHON_VENV_BINARIES PYTHON_VENV_PACKAGES \
OPEN DOWN VERT SPLT __UP SHUT; do
value="$(spcd_os_printenv "SPCD_${variable}")"
text="${text}${value}
"
done
index=$((__SPCD_STEP_1_INDEX + 1))
for root in \
"${SPCD_PYTHON_PACKAGES}" "${SPCD_PYTHON_VENV_PACKAGES}"; do
spcd_os_write "${root}/env.py" "${text}
SPCD_STEP = ${index}
"
done
}
spcd_f_py_switch() {
spcd_step "Switch"
local name path
name="$(basename "${SPCD_GIT_SPCD}")"
path="$(realpath "${0}")"
echo "\
${path}
${SPCD_PYTHON_ALIAS} / ${name}"
"${SPCD_PYTHON_ALIAS}" -m "${name}"
}
# ╭───┬─────╮
# │ f │ txt │
# ╰───┴─────╯
@ -1367,9 +1170,22 @@ ${name}.${_SPCD_TXT_CHARSET} ${_SPCD_TXT_CHARSET}
esac
}
# ╭──────┬──────────╮
# │ step │ packages │
# ╰──────┴──────────╯
# ╭───┬──────╮
# │ s = step │
# ╰───┴──────╯
# ╭───┬─────╮
# │ s │ dns │
# ╰───┴─────╯
spcd_step__dns() {
spcd_step "DNS"
spcd_dns "write"
}
# ╭───┬──────────╮
# │ s │ packages │
# ╰───┴──────────╯
spcd_step__packages_set_repositories() {
spcd_step "Set repositories"
@ -1552,6 +1368,191 @@ Dir::Etc::SourceParts \"\";
esac
}
# ╭───┬──────────╮
# │ s │ packages │
# ╰───┴──────────╯
spcd_step__packages_install_dos2unix() {
spcd_step "Install dos2unix"
spcd_f_pm_pkg_install "dos2unix"
}
spcd_step__packages_install_git() {
spcd_step "Install Git"
spcd_f_pm_pkg_install "git"
}
# ╭───┬────────╮
# │ s │ python │
# ╰───┴────────╯
spcd_step__python_install() {
spcd_step "Install package"
spcd_f_pm_pkg_install "${SPCD_PYTHON_PACKAGE}"
spcd_step "Link alias to command"
spcd_python_ln "${SPCD_PYTHON_COMMAND}"
# venv
spcd_step_in "Virtual environment"
spcd_step "Install package"
case "${SPCD_OS_ID}" in
"${SPCD_OS_DEBIAN}" | "${SPCD_OS_UBUNTU}")
spcd_f_pm_pkg_install "python3-venv"
;;
*) ;;
esac
spcd_step "Configure PIP"
spcd_os_write "/etc/pip.conf" "\
[global]
index-url = ${SPCD_URL_PYTHON}/simple
"
spcd_step "Create"
"${SPCD_PYTHON_ALIAS}" -m "venv" "${SPCD_PYTHON_VENV}"
spcd_step "Activate"
export PATH="${SPCD_PYTHON_VENV_BINARIES}:${PATH}"
export VIRTUAL_ENV="${SPCD_PYTHON_VENV}"
spcd_step_out
}
spcd_step__python_modules() {
spcd_step_in "Modules"
local target path script check
target="${SPCD_PYTHON_VENV_PACKAGES}"
spcd_step "List"
spcd_os_ls "${target}"
spcd_step "Main"
path="$(spcd_python_pip "${SPCD_GIT_SPCD}")"
# check matching of file and variable
spcd_step "Check"
script="${path}/bootstrap.sh"
ls -l "${script}"
check="${script}.${_SPCD_CMD_SUM}"
"${_SPCD_CMD_SUM}" "${script}" >"${check}"
printf "%s" "${SPCD}" >"${script}"
ls -l "${script}"
dos2unix "${script}"
ls -l "${script}"
"${_SPCD_CMD_SUM}" -c "${check}" || spcd_error_ci "SPCD"
spcd_step "Root"
spcd_python_pip "${SPCD_GIT_RWX}"
spcd_step "List"
spcd_os_ls "${target}"
spcd_step_out
}
spcd_step__install_packages() {
spcd_step_in "OS packages"
local file
# epel
spcd_step "EPEL"
case "${SPCD_OS_ID}" in
"${SPCD_OS_ALMA}" | "${SPCD_OS_ROCKY}")
spcd_f_pm_pkg_install "epel-release"
case "${SPCD_OS_VERSION}" in
"9")
set -- \
"-testing" \
""
;;
"8")
set -- \
"-modular" \
"-testing-modular" \
"-testing" \
""
;;
*) ;;
esac
for file in "${@}"; do
spcd_os_sed "/etc/yum.repos.d/epel${file}.repo" \
"|^metalink|#metalink|" \
"|https://download.example/pub/epel|${SPCD_URL_EPEL}|" \
"|^#baseurl|baseurl|"
done
file="/etc/yum.repos.d/epel-cisco-openh264.repo"
if [ -f "${file}" ]; then
spcd_os_sed "${file}" \
"|^enabled=1|enabled=0|"
fi
;;
*) ;;
esac
# graphviz
spcd_step "GraphViz"
spcd_f_pm_pkg_install "graphviz"
# openssh
spcd_step "OpenSSH"
case "${SPCD_PM}" in
"${SPCD_PM_APK}" | "${SPCD_PM_APT}")
spcd_f_pm_pkg_install "openssh-client"
;;
"${SPCD_PM_DNF}" | "${SPCD_PM_ZYPPER}")
spcd_f_pm_pkg_install "openssh-clients"
;;
"${SPCD_PM_PACMAN}") spcd_f_pm_pkg_install "openssh" ;;
*) ;;
esac
# plantuml
spcd_step "PlantUML"
spcd_f_pm_pkg_install "plantuml"
# rsync
spcd_step "Rsync"
spcd_f_pm_pkg_install "rsync"
# shell check
spcd_step "ShellCheck"
case "${SPCD_PM}" in
"${SPCD_PM_DNF}" | "${SPCD_PM_ZYPPER}")
spcd_f_pm_pkg_install "ShellCheck"
;;
*) spcd_f_pm_pkg_install "shellcheck" ;;
esac
# shfmt
spcd_step "ShellFormat"
case "${SPCD_OS_ID}" in
"${SPCD_OS_ALMA}" | "${SPCD_OS_ROCKY}") ;;
"${SPCD_OS_DEBIAN}")
case "${SPCD_OS_VERSION}" in
"bullseye") ;;
*) spcd_f_pm_pkg_install "shfmt" ;;
esac
;;
*) spcd_f_pm_pkg_install "shfmt" ;;
esac
spcd_step_out
}
spcd_step__python_write_module() {
spcd_step "Write module"
local variable value text index root
for variable in \
OS_ID OS_VERSION \
PROJECT_ROOT PROJECT_PATH PROJECT_NAME \
PYTHON_VENV_BINARIES PYTHON_VENV_PACKAGES \
OPEN DOWN VERT SPLT __UP SHUT; do
value="$(spcd_os_printenv "SPCD_${variable}")"
text="${text}${value}
"
done
index=$((__SPCD_STEP_1_INDEX + 1))
for root in \
"${SPCD_PYTHON_PACKAGES}" "${SPCD_PYTHON_VENV_PACKAGES}"; do
spcd_os_write "${root}/env.py" "${text}
SPCD_STEP = ${index}
"
done
}
spcd_step__python_switch() {
spcd_step "Switch"
local name path
name="$(basename "${SPCD_GIT_SPCD}")"
path="$(realpath "${0}")"
echo "\
${path}
${SPCD_PYTHON_ALIAS} / ${name}"
"${SPCD_PYTHON_ALIAS}" -m "${name}"
}
# ╭──────╮
# │ main │
# ╰──────╯
@ -1567,19 +1568,17 @@ spcd_main() {
spcd_step__environment_print
spcd_step_out
spcd_step__environment_set_variables
spcd_step "List workspace"
spcd_f_env_workspace
spcd_step__environment_list_workspace
spcd_step_out
# dns
spcd_step "DNS"
spcd_f_dns "write"
spcd_step__dns
# packages
spcd_step_in "Packages"
spcd_step__packages_set_repositories
spcd_step__packages_set_configuration
spcd_f_pm_https_trust
spcd_f_pm_pkg_update
spcd_f_pm_pkg_install
spcd_f_pm_install
# locales
spcd_step_in "Locales"
spcd_step "Install"
@ -1593,7 +1592,7 @@ spcd_main() {
# ca
spcd_step_in "CA"
spcd_f_ca_install
spcd_f_ca "write"
spcd_f_ca_write
spcd_f_ca_update
spcd_step_out
# packages
@ -1601,16 +1600,16 @@ spcd_main() {
spcd_f_pm_https_verify
spcd_f_pm_pkg_update
spcd_f_pm_pkg_upgrade
spcd_f_pkg_dos2unix
spcd_f_pkg_git
spcd_step__packages_install_dos2unix
spcd_step__packages_install_git
spcd_step_out
# python
spcd_step_in "Python"
spcd_f_py_install
spcd_f_py_download
spcd_f_pkg
spcd_f_py_save
spcd_f_py_switch
spcd_step__python_install
spcd_step__python_modules
spcd_step__install_packages
spcd_step__python_write_module
spcd_step__python_switch
}
spcd_main