Compare commits

...

14 commits
v0.1.2 ... main

34 changed files with 118 additions and 490 deletions

2
.envrc
View file

@ -1,3 +1 @@
use nix
export BASHLY_SOURCE_DIR=$(cat .target)

View file

@ -3,45 +3,30 @@ on:
tags:
- v**
jobs:
build-artifacts:
release:
runs-on: docker
strategy:
matrix:
tool:
- autoinstall
- autostart-manage
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- id: install-dependencies
run: |
apt update
# TODO add pandoc for docs
apt install -y make ruby
gem install bashly
shell: bash
- id: run-bashly
run: |
echo "${{ matrix.tool }}" > .target
make generate
#make docs
shell: bash
- uses: https://code.forgejo.org/actions/upload-artifact@v3
with:
name: ${{ matrix.tool }}
path: ${{ github.workspace }}/output/${{ matrix.tool }}
upload-release:
runs-on: docker
steps:
- uses: https://code.forgejo.org/actions/checkout@v3
- uses: https://code.forgejo.org/actions/download-artifact@v3
with:
path: /tmp/artifacts-in
merge-multiple: true # broken "collect-artifacts" used as workaround
- id: collect-artifacts
- id: prepare-release
run: |
mkdir /tmp/artifacts-out
mv $(find /tmp/artifacts-in -type f) /tmp/artifacts-out
mkdir /tmp/release
cp ./autostart-manage /tmp/release
#cp -r ./man1 /tmp/release
shell: bash
- uses: https://code.forgejo.org/actions/forgejo-release@v1
with:
direction: upload
release-dir: /tmp/artifacts-out
release-dir: /tmp/release
token: ${{ github.token }}

7
.gitignore vendored
View file

@ -1,5 +1,4 @@
.target
output/
src/lib/send_completions.sh
autoinstall/lib/send_completions.sh
autostart-manage/lib/send_completions.sh
autostart-manage
man1

View file

@ -1,22 +1,12 @@
target:
@echo "Select target directory"
@echo $$(find . -name bashly.yml | sed -e 's/.\///' -e 's/\/.*//' | $$DMENU) > .target
completions:
bashly add completions
get-target:
$(eval TARGET := $(shell cat .target))
output-dir:
mkdir -p ./output
completions: get-target
BASHLY_SOURCE_DIR=$(TARGET) bashly add completions
generate: get-target output-dir completions
BASHLY_SOURCE_DIR=$(TARGET) bashly generate --upgrade
generate: completions
bashly generate --upgrade
docs: generate
BASHLY_SOURCE_DIR=$(TARGET) bashly render :mandoc ./output/man1
bashly render :mandoc ./man1
deploy: generate docs
cp -f ./output/$(TARGET) ~/.local/bin/
cp -f ./output/man1/$(TARGET)*.1 ~/.local/share/man/man1/
install: generate docs
cp -f ./autostart-manage ~/.local/bin/
cp -f ./man1/autostart-manage*.1 ~/.local/share/man/man1/

View file

@ -1,18 +0,0 @@
#!/usr/bin/env bash
target=${args[target]:?}
url=${args[url]:?}
if [ ! -f "$target" ]
then
echo "Installing archive $url to $target"
target_dir=$(dirname "$target")
mkdir -p "$target_dir"
cd "$target_dir" || exit 1
_http_client "$url" > "$target"
tar xaf "$target"
_run_hook
fi

View file

@ -1,111 +0,0 @@
name: autoinstall
help: Install files, repository and else
version: 0.1.2
flags:
- long: --clean
short: -c
help: Clean exisiting targets
- long: --hook
short: -h
help: Hook to run if something changed
arg: hook
environment_variables:
- name: AUTOINSTALL_CLEAN
help: Clean exisiting targets
dependencies:
http_client:
command: [curl, wget]
help: Please install either curl or wget
commands:
- name: completions
help: Generate bash completions
- name: run
help: Autoinstall from file
args:
- name: group
required: true
help: The group to install
- name: git
help: Install a git repository
args:
- name: repo
required: true
help: The url of the git repository
- name: target
required: true
help: The path to clone the repository into
- name: file
help: Install a file
args:
- name: url
required: true
help: The url of the file
- name: target
required: true
help: The file-path to download the file into
flags:
- long: --pipe
short: -p
help: Pipe file through command (e.g. "tar xzO")
arg: pipe
default: cat
- name: exe
help: Install an executable
args:
- name: url
required: true
help: The url of the file
- name: target
required: true
help: The file-path to download the file into
filename: file_command.sh
flags:
- long: --pipe
short: -f
help: Pipe file through command (e.g. "tar xzO")
arg: pipe
default: cat
- long: --completions
short: -c
help: Run a command on the new exe to install completions
arg: completions
- name: archive
help: Install an archive
args:
- name: url
required: true
help: The url of the arhive
- name: target
required: true
help: The path to clone the repository into
- name: env
help: Create a file with envsubst
args:
- name: template
required: true
help: The path to the template
- name: target
required: true
help: The path to write the result to
dependencies:
envsubst: This tool is usually part of the gettext package
- name: text
help: Create a file from text
args:
- name: text
required: true
help: The text to write to the file
- name: target
required: true
help: The path to write the result to

View file

@ -1,23 +0,0 @@
#!/usr/bin/env bash
action=${action:?}
# if action is run or completions, do nothing
if [ "$action" = "run" ] || [ "$action" = "completions" ]
then
return
fi
clean=${args[--clean]:-}
target=${args[target]:?}
if [ "$action" = "exe" ]
then
target="$HOME/.local/bin/$target"
fi
if [ -n "$clean" ] || [ -n "${AUTOINSTALL_CLEAN:-}" ]
then
echo "Cleaning $target"
rm -rf "$target"
fi

View file

@ -1,17 +0,0 @@
#!/usr/bin/env bash
target=${args[target]:?}
template=${args[template]:?}
if [ ! -f "$target" ]
then
echo "Installing env-template $template to $target"
target_dir=$(dirname "$target")
mkdir -p "$target_dir"
cd "$target_dir" || exit 1
envsubst < "$template" > "$target"
_run_hook
fi

View file

@ -1,45 +0,0 @@
#!/usr/bin/env bash
pipe=${args[--pipe]:?}
completions=${args[--completions]:-}
target=${args[target]:?}
url=${args[url]:?}
if [ "${action:-file}" = "exe" ]
then
if [ -x "$(command -v "$target")" ]
then
return
fi
exe=$target
target="$HOME/.local/bin/$target"
fi
if [ ! -f "$target" ]
then
echo "Installing file $url to $target"
target_dir=$(dirname "$target")
mkdir -p "$target_dir"
cd "$target_dir" || exit 1
_http_client "$url" | eval "$pipe" > "$target"
if [ "${action:-file}" = "exe" ]
then
chmod +x "$target"
if [ -n "$completions" ]
then
echo "Installing completions for $exe"
# path taken from "__load_completion" function
bash_completions_dir=${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions
mkdir -p "$bash_completions_dir"
eval "$target $completions" > "$bash_completions_dir/_$(basename "$exe")"
fi
fi
_run_hook
fi

View file

@ -1,15 +0,0 @@
#!/usr/bin/env bash
target=${args[target]:?}
repo=${args[repo]:?}
if [ ! -d "$target" ]
then
echo "Installing repo $repo to $target"
mkdir -p "$target"
git clone --depth=1 "$repo" "$target" >/dev/null 2>&1
_run_hook
fi

View file

@ -1,42 +0,0 @@
## Color functions [@bashly-upgrade colors]
## This file is a part of Bashly standard library
##
## Usage:
## Use any of the functions below to color or format a portion of a string.
##
## echo "before $(red this is red) after"
## echo "before $(green_bold this is green_bold) after"
##
## Color output will be disabled if `NO_COLOR` environment variable is set
## in compliance with https://no-color.org/
##
print_in_color() {
local color="$1"
shift
if [[ -z ${NO_COLOR+x} ]]; then
printf "$color%b\e[0m\n" "$*"
else
printf "%b\n" "$*"
fi
}
red() { print_in_color "\e[31m" "$*"; }
green() { print_in_color "\e[32m" "$*"; }
yellow() { print_in_color "\e[33m" "$*"; }
blue() { print_in_color "\e[34m" "$*"; }
magenta() { print_in_color "\e[35m" "$*"; }
cyan() { print_in_color "\e[36m" "$*"; }
bold() { print_in_color "\e[1m" "$*"; }
underlined() { print_in_color "\e[4m" "$*"; }
red_bold() { print_in_color "\e[1;31m" "$*"; }
green_bold() { print_in_color "\e[1;32m" "$*"; }
yellow_bold() { print_in_color "\e[1;33m" "$*"; }
blue_bold() { print_in_color "\e[1;34m" "$*"; }
magenta_bold() { print_in_color "\e[1;35m" "$*"; }
cyan_bold() { print_in_color "\e[1;36m" "$*"; }
red_underlined() { print_in_color "\e[4;31m" "$*"; }
green_underlined() { print_in_color "\e[4;32m" "$*"; }
yellow_underlined() { print_in_color "\e[4;33m" "$*"; }
blue_underlined() { print_in_color "\e[4;34m" "$*"; }
magenta_underlined() { print_in_color "\e[4;35m" "$*"; }
cyan_underlined() { print_in_color "\e[4;36m" "$*"; }

View file

@ -1,20 +0,0 @@
#!/usr/bin/env bash
_http_client() {
if [ -x "$(command -v curl)" ]
then
curl -fsSL "$1"
elif [ -x "$(command -v wget)" ]
then
wget -qO - "$1"
fi
}
_run_hook() {
hook=${args[--hook]:-}
if [ -n "$hook" ]
then
yellow "Running hook: $hook"
bash -c "$hook"
fi
}

View file

@ -1,47 +0,0 @@
#!/usr/bin/env bash
group=${args[group]:?}
clean=${args[--clean]:-}
_config_query() {
tomlq -c --arg group "$group" \
'.autoinstall | map(select(.groups + ["all"] | contains([$group]))) | '"$1" \
"$XDG_CONFIG_HOME/autoinstall.toml"
}
_config_query ".[]" | while read -r entry; do
install_args=()
type=$(echo "$entry" | jq -r '.type')
source=$(echo "$entry" | jq -r '.source')
target=$(echo "$entry" | jq -r '.target')
hook=$(echo "$entry" | jq -r '.hook // ""')
pipe=$(echo "$entry" | jq -r '.pipe // ""')
completions=$(echo "$entry" | jq -r '.completions // ""')
if [[ -n "$hook" ]]; then
install_args+=("--hook=$hook")
fi
if [[ -n "$clean" ]]; then
install_args+=("--clean")
fi
install_args+=("$type")
if [[ -n "$pipe" ]]; then
install_args+=("--pipe=$pipe")
fi
if [[ -n "$completions" ]]; then
install_args+=("--completions=$completions")
fi
if [[ $source = \$* ]]
then
source=$(eval "echo $source")
fi
install_args+=("$source")
install_args+=("$(eval "echo $target")")
autoinstall "${install_args[@]}"
done

View file

@ -1,16 +0,0 @@
#!/usr/bin/env bash
target=${args[target]:?}
text=${args[text]:?}
if [ ! -f "$target" ]
then
echo "Installing text '$text' to $target"
target_dir=$(dirname "$target")
mkdir -p "$target_dir"
echo "$text" > "$target"
_run_hook
fi

View file

@ -1,3 +0,0 @@
#!/usr/bin/env bash
send_completions

View file

@ -1,3 +0,0 @@
#!/usr/bin/env bash
journalctl --user -fu "autostart@${args[program]:?}.service"

View file

@ -1,14 +0,0 @@
#!/usr/bin/env bash
rm "$HOME/.config/systemd/user/autostart.target.wants/"*
autostart_units=()
while IFS='' read -r line
do
autostart_units+=("$line")
done < <(_list)
for unit in "${autostart_units[@]}"
do
_systemctl "$unit" add-wants autostart.target
done

8
run.sh
View file

@ -1,9 +1,7 @@
#!/usr/bin/env sh
target=$(cat .target)
[ -n "$target" ] || exit 1
make generate
"./output/$target" "$@"
printf "\nBuild complete. Running...\n==========================\n\n"
time ./autostart-manage "$@"

View file

@ -1,49 +0,0 @@
# The path to bashly.yml
config_path: "%{source_dir}/bashly.yml"
# The path to use for creating the bash script
target_dir: output
# The path to use for common library files, relative to source_dir
lib_dir: lib
# The path to use for command files, relative to source_dir
# When set to nil (~), command files will be placed directly under source_dir
# When set to any other string, command files will be placed under this
# directory, and each command will get its own subdirectory
commands_dir: ~
# Configure the bash options that will be added to the initialize function:
# strict: true Bash strict mode (set -euo pipefail)
# strict: false Only exit on errors (set -e)
# strict: '' Do not add any 'set' directive
# strict: <string> Add any other custom 'set' directive
strict: true
# When true, the generated script will use tab indentation instead of spaces
# (every 2 leading spaces will be converted to a tab character)
tab_indent: true
# When true, the generated script will consider any argument in the form of
# `-abc` as if it is `-a -b -c`.
compact_short_flags: true
# Set to 'production' or 'development':
# env: production Generate a smaller script, without file markers
# env: development Generate with file markers
env: development
# The extension to use when reading/writing partial script snippets
partials_extension: sh
# Display various usage elements in color by providing the name of the color
# function. The value for each property is a name of a function that is
# available in your script, for example: `green` or `bold`.
# You can run `bashly add colors` to add a standard colors library.
# This option cannot be set via environment variables.
usage_colors:
caption: blue
command: green
arg: red
flag: yellow
environment_variable: cyan

View file

@ -1,6 +1,6 @@
name: autostart-manage
help: Manage autostart
version: 0.1.2
version: 0.1.4
dependencies:
tomlq: please install yq (https://github.com/kislyuk/yq)
@ -19,6 +19,10 @@ commands:
help: Get the current status of all programs
- name: sync
help: Remove all programs from autostart and the re-enable all
args:
- name: groups
required: false
help: Extra groups to sync
- name: enable
help: Add a single program to autostart
args:
@ -73,6 +77,15 @@ commands:
completions:
- $(autostart-manage list)
filename: systemctl.sh
- name: kill
help: Kill the program from autostart
args:
- name: program
required: true
help: Program to kill
completions:
- $(autostart-manage list)
filename: systemctl.sh
- name: log
alias: logs
help: Show the log for a single program from autostart

11
src/before.sh Normal file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env bash
service_file="$HOME/.config/systemd/user/autostart@.service"
if [ ! -f "$service_file" ]; then
_deploy_service_file "$service_file"
fi
target_file="$HOME/.config/systemd/user/autostart.target"
if [ ! -f "$target_file" ]; then
_deploy_target_file "$target_file"
fi

View file

@ -2,6 +2,5 @@
program=${args[program]:?}
cmd=$(_get_autostart_cmd "$program")
sleep "$(_get_autostart_delay "$program")"
bash -c "$cmd"
bash -c "$(_get_autostart_cmd "$program")"

View file

@ -4,6 +4,6 @@ autostart_units=()
while IFS='' read -r line
do
autostart_units+=("$line")
done < <(_list)
done < <(_list "*")
_echo_table "${autostart_units[@]}" | column -t -s$'\t' --table-columns 'Unit,Enabled?,Active?,Command'

View file

@ -26,17 +26,26 @@ yellow() { print_in_color "\e[33m" "$*"; }
blue() { print_in_color "\e[34m" "$*"; }
magenta() { print_in_color "\e[35m" "$*"; }
cyan() { print_in_color "\e[36m" "$*"; }
black() { print_in_color "\e[30m" "$*"; }
white() { print_in_color "\e[37m" "$*"; }
bold() { print_in_color "\e[1m" "$*"; }
underlined() { print_in_color "\e[4m" "$*"; }
red_bold() { print_in_color "\e[1;31m" "$*"; }
green_bold() { print_in_color "\e[1;32m" "$*"; }
yellow_bold() { print_in_color "\e[1;33m" "$*"; }
blue_bold() { print_in_color "\e[1;34m" "$*"; }
magenta_bold() { print_in_color "\e[1;35m" "$*"; }
cyan_bold() { print_in_color "\e[1;36m" "$*"; }
black_bold() { print_in_color "\e[1;30m" "$*"; }
white_bold() { print_in_color "\e[1;37m" "$*"; }
red_underlined() { print_in_color "\e[4;31m" "$*"; }
green_underlined() { print_in_color "\e[4;32m" "$*"; }
yellow_underlined() { print_in_color "\e[4;33m" "$*"; }
blue_underlined() { print_in_color "\e[4;34m" "$*"; }
magenta_underlined() { print_in_color "\e[4;35m" "$*"; }
cyan_underlined() { print_in_color "\e[4;36m" "$*"; }
black_underlined() { print_in_color "\e[4;30m" "$*"; }
white_underlined() { print_in_color "\e[4;37m" "$*"; }

View file

@ -5,16 +5,25 @@ _systemctl () {
}
_query_autostart_toml() {
tomlq -r --arg host "$HOSTNAME" \
'.hosts[$host].groups as $groups | .apps | to_entries[] | select(
(.value.hosts | contains([$host])) or
([.value.group] | inside($groups))
) | '"$1" \
"$XDG_CONFIG_HOME/autostart.toml"
groups_json=$(echo -n "$2" | tr "," "\n" | jq -R . | jq -s .)
tomlq -r \
--arg host "$HOSTNAME" \
--argjson extra_groups "$groups_json" \
'.hosts[$host].groups as $groups | .apps | to_entries[] | select(
(.value.hosts | contains([$host])) or
(
(
([.value.group] | inside($groups)) or
([.value.group] | inside($extra_groups)) or
$extra_groups == ["*"]
) and (.value.group != "")
)
) | '"$1" \
"$XDG_CONFIG_HOME/autostart.toml"
}
_list () {
_query_autostart_toml '.value.alias // .key'
_query_autostart_toml '.value.alias // .key' "$1"
}
_autostart_run_graphical () {
@ -41,7 +50,7 @@ _autostart_run_graphical () {
_echo_table () {
for unit in "$@"
do
if _systemctl "$unit" is-enabled --quiet
if [ "$(_systemctl "$unit" is-enabled)" = "enabled" ]
then
_enabled=$(green "enabled")
else
@ -64,9 +73,9 @@ _echo_table () {
}
_get_autostart_cmd () {
_query_autostart_toml 'select((.key == "'"$1"'") or (.value.alias == "'"$1"'")) | .value.command'
_query_autostart_toml 'select((.key == "'"$1"'") or (.value.alias == "'"$1"'")) | .value.command' "*"
}
_get_autostart_delay () {
_query_autostart_toml 'select((.key == "'"$1"'") or (.value.alias == "'"$1"'")) | .value.delay // 0'
_query_autostart_toml 'select((.key == "'"$1"'") or (.value.alias == "'"$1"'")) | .value.delay // 0' "*"
}

26
src/lib/systemd_files.sh Normal file
View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
_deploy_service_file() {
cat <<EOF > "$1"
[Unit]
Description=Autostart several tools and services
StartLimitIntervalSec=120
StartLimitBurst=10
[Service]
KillMode=process
ExecStart=/bin/sh -c ". \$HOME/.profile && autostart-manage exec '%i'"
Restart=on-failure
RestartSec=5s
EOF
}
_deploy_target_file() {
cat <<EOF > "$1"
[Unit]
Description=Current graphical user session
Documentation=man:systemd.special(7)
RefuseManualStart=no
StopWhenUnneeded=no
EOF
}

View file

@ -1,3 +1,3 @@
#!/usr/bin/env bash
_list
_list "*"

3
src/log_command.sh Normal file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
journalctl --user -b0 -fu "autostart@${args[program]:?}.service"

11
src/sync_command.sh Normal file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env bash
rm -f "$HOME/.config/systemd/user/autostart.target.wants/"*
autostart_units=()
while IFS='' read -r line
do
autostart_units+=("autostart@$line.service")
done < <(_list "${args[groups]:-}")
systemctl --user add-wants autostart.target "${autostart_units[@]}"