17 Commits

Author SHA1 Message Date
d20cba3e15 Replace Magnet with Rectangle 2025-12-02 23:23:48 +00:00
27f887b044 Actually output yaml in results 2025-12-02 23:08:50 +00:00
c70a31b633 Install iSMC as part of system-info role 2025-11-26 22:35:06 +00:00
80434f1cfa Add tuck module 2025-11-26 22:33:15 +00:00
658e35a145 Explicitly enable inject_facts_as_vars
Injecting facts as variables is being deprecated by default, override
this in `ansible.cfg` to silence deprecation warnings.
2025-11-26 20:50:00 +00:00
06a4d1b923 Remove corepack from nodejs role 2025-11-23 11:17:38 +00:00
fe220c231a Also install hammerspoon spoons 2025-11-11 23:00:33 +00:00
e633da1e7c Add hammerspoon role 2025-11-06 20:56:42 +00:00
7823cfb683 Ensure gawk is install on macOS for system-info 2025-10-30 17:42:19 +00:00
0a385259a5 Add work specific macOS playbook 2025-10-30 15:41:45 +00:00
cf77532254 Add todo to macos role 2025-10-30 15:41:31 +00:00
7e2a813682 Fix system-info role on macOS fresh install 2025-10-30 15:40:40 +00:00
9bd29dcdd2 Add fedora-workstation role
Install non-free gstreamer plugins
2025-08-26 15:05:12 +01:00
173c7261b3 Add todo to gnome-shell role 2025-08-18 22:30:31 +01:00
ee3ea63383 Add gemini-cli role 2025-08-18 22:30:22 +01:00
d41ea98da0 Add typst role 2025-08-18 13:00:27 +01:00
77a4fdcc16 Add nvtop role 2025-08-17 22:10:44 +01:00
21 changed files with 391 additions and 8 deletions

View File

@@ -2,4 +2,5 @@
collections_path = collections
library = library
roles_path = roles
result_format = yaml
callback_result_format = yaml
inject_facts_as_vars = True

121
library/tuck.py Normal file
View File

@@ -0,0 +1,121 @@
# -*- coding: utf-8 -*-
import os
import subprocess
from os import environ
from pathlib import Path
import requests
from ansible.module_utils.basic import AnsibleModule
DOCUMENTATION = """
module: tuck
author:
- Kenneth Benzie (Benie)
short_description: Ansible kmodule for the tuck tool
options:
name:
description:
- GitHub project name of the package to manage
type: str
state:
description:
- Desired state of the package
type: str
choices:
- "latest"
- "absent"
"""
EXAMPLES = """
- name: install package
tuck:
name: kbenzie/tuck
state: present
- name: uninstall package
tuck:
name: kbenzie/tuck
state: absent
"""
def installed(tuck) -> list[str]:
result = subprocess.run(
[tuck, "list", "--quiet"],
capture_output=True,
check=True,
)
return result.stdout.decode("utf-8").split("\n")
def present(tuck: Path, package: str) -> dict:
if package in installed(tuck):
return dict(changed=False)
return latest(tuck, package)
def latest(tuck: Path, package: str) -> dict:
result = subprocess.run(
[tuck, "install", package],
capture_output=True,
check=True,
)
return dict(changed=True, stdout=result.stdout)
def absent(tuck: Path, package: str) -> dict:
if package not in installed(tuck):
return dict(changed=False)
result = subprocess.run(
[tuck, "remove", package],
capture_output=True,
check=True,
)
return dict(changed=True, stdout=result.stdout)
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type="str"),
state=dict(
type="str",
choices=[
"absent",
"latest",
"present",
],
default="present",
),
),
supports_check_mode=False,
)
tuck = Path(environ["HOME"]) / ".local" / "bin" / "tuck"
try:
if not (tuck.is_file() and os.access(tuck, os.X_OK)):
response = requests.get("https://kbenzie.github.io/tuck/get.sh")
response.raise_for_status()
subprocess.run(
["/bin/sh"],
input=response.text.encode("utf-8"),
check=True,
)
module.exit_json(
**{
"absent": absent,
"present": present,
"latest": latest,
}[module.params["state"]](tuck, module.params["name"])
)
except requests.RequestException as error:
module.fail_json(f"failed to install tuck: {error}")
except subprocess.CalledProcessError as error:
module.fail_json(f"failed to install tuck: {error.stderr}")
if __name__ == "__main__":
main()

View File

@@ -13,3 +13,5 @@
when: "'GNOME' in ansible_env.XDG_CURRENT_DESKTOP"
- role: xremap
when: "'GNOME' in ansible_env.XDG_CURRENT_DESKTOP"
- role: fedora-workstation
when: ansible_os_family == 'RedHat' and ansible_distribution == 'Fedora'

View File

@@ -11,6 +11,7 @@
- vars/environment.yaml
roles:
- role: gdb
- role: nvtop
- role: podman
- role: system-info
when: disable_systemd is not defined

View File

@@ -30,6 +30,7 @@
- role: ripgrep
- role: tidy
- role: tree
- role: typst
- role: watch
- role: wget
- role: yq

View File

@@ -20,6 +20,7 @@
- role: jq
- role: ripgrep
- role: tree
- role: typst
- role: yq
- role: llvm

12
playbooks/macOS-work.yaml Normal file
View File

@@ -0,0 +1,12 @@
---
- import_playbook: UnixCLI.yaml
- hosts: localhost
vars_files:
- vars/environment.yaml
roles:
- role: system-info
- role: fonts
- role: iterm
- role: kitty
- role: neovide
- role: macos

View File

@@ -16,7 +16,7 @@
- role: iterm
- role: kitty
- role: neovide
- role: magnet
- role: rectangle
- role: windows-app
- role: viscosity

View File

@@ -0,0 +1,16 @@
---
- assert:
that: ansible_os_family == 'RedHat' and ansible_distribution == 'Fedora'
- name: install non-free gstreamer plugins
become: true
dnf:
state: latest
allowerasing: true
name:
- ffmpeg
- gstreamer1-plugins-bad-free
- gstreamer1-plugins-bad-freeworld
- gstreamer1-plugins-base
- gstreamer1-plugins-good
- gstreamer1-plugins-ugly

View File

@@ -0,0 +1,14 @@
---
- name: install homebrew package
when: ansible_os_family == 'Darwin'
homebrew:
state: latest
name: gemini-cli
- name: install npm package
when: ansible_os_family != 'Darwin'
become: true
community.general.npm:
name: '@google/gemini-cli'
state: latest
global: true

View File

@@ -33,6 +33,8 @@
key: switch-input-source-backward
value: '@as []'
# TODO: window full screen toggle keybinding
# NOTE: Use this command to see default keybindings
# gsettings list-recursively | grep -i -E 'media-keys|keybindings'
# NOTE: Use this command to inspect the current state of the custom keybindings

View File

@@ -0,0 +1,29 @@
---
- set_fact:
config_dir: '{{ansible_env.HOME}}/.hammerspoon'
- name: create config directory
file:
state: directory
path: '{{config_dir}}'
- name: install config file
template:
src: init.lua
dest: '{{config_dir}}/init.lua'
- name: install homebrew package
homebrew:
state: latest
name: hammerspoon
- name: create spoons directory
file:
state: directory
path: '{{config_dir}}/Spoons'
- name: install SpoonInstall Spoon
unarchive:
src: https://github.com/Hammerspoon/Spoons/raw/master/Spoons/SpoonInstall.spoon.zip
dest: '{{config_dir}}/Spoons'
remote_src: yes

View File

@@ -0,0 +1,20 @@
require('hs.ipc')
hs.loadSpoon("SpoonInstall")
spoon.SpoonInstall:andUse("EmmyLua")
hs.hotkey.bind({'alt', 'cmd'}, 'B', function()
hs.application.launchOrFocus('Firefox')
end)
hs.hotkey.bind({'alt', 'cmd'}, 'T', function()
hs.application.launchOrFocus('kitty')
end)
hs.hotkey.bind({'alt', 'cmd'}, 'F', function()
hs.application.launchOrFocus('Ferdium')
end)
pcall(function()
require('local')
end)

View File

@@ -7,3 +7,5 @@
domain: com.apple.desktopservices
key: DSDontWriteNetworkStores
value: 'true'
# TODO: ^Space Keyboard Shortcut for switching Input Sources

View File

@@ -26,4 +26,4 @@
state: link
src: '~/.local/src/node/node-{{latest.json[0].version}}-linux-x64/bin/{{item}}'
dest: '~/.local/bin/{{item}}'
with_items: [corepack, node, npm, npx]
with_items: [node, npm, npx]

View File

@@ -0,0 +1,40 @@
---
- name: get latest github release
uri:
url: https://api.github.com/repos/Syllo/nvtop/releases/latest
headers: '{{github_auth_headers}}'
register: latest
- set_fact:
asset_query: '[?contains(name, `x86_64.AppImage`)] | [0]'
assets: '{{latest.json.assets}}'
latest_version: '{{latest.json.tag_name}}'
nvtop_exe: '/usr/local/bin/nvtop'
- name: check if already installed
stat:
path: '{{nvtop_exe}}'
register: nvtop_stat
- name: get installed version
when: nvtop_stat.stat.exists == True
command: '{{nvtop_exe}} --version'
register: nvtop_version_output
changed_when: false
- when: nvtop_stat.stat.exists == True
set_fact:
installed_version:
'{{nvtop_version_output.stdout.strip() | regex_replace("^.*(\d+\.\d+\.\d+).*$", "\1")}}'
- set_fact:
asset: '{{assets | to_json | from_json | json_query(asset_query)}}'
- name: download executable
when: installed_version is not defined or installed_version != latest_version
become: true
get_url:
url: '{{asset.browser_download_url}}'
dest: '{{nvtop_exe}}'
mode: +x
environment: '{{proxy_environment}}'

View File

@@ -0,0 +1,10 @@
---
- name: install dnf package
when: ansible_os_family == 'RedHat'
become: true
dnf:
state: latest
name: nvtop
- when: ansible_os_family != 'RedHat'
include_tasks: install-appimage.yaml

View File

@@ -2,7 +2,7 @@
- assert:
that: ansible_os_family == 'Darwin'
- name: install app store package
mas:
id: 441258766
- name: install homebrew package
homebrew_cask:
name: rectangle
state: latest

View File

@@ -1,14 +1,34 @@
---
- name: install gawk package
homebrew:
name: gawk
state: latest
- name: install iSMC package
tuck:
name: dkorunic/iSMC
state: latest
- name: get list of running launchd services
command: launchctl list
register: launchd_running_services
changed_when: false
- set_fact:
system_info_plist_dir: '{{ansible_env.HOME}}/Library/LaunchAgents'
- name: create plist directory
file:
state: directory
path: '{{system_info_plist_dir}}'
- name: determine if system-info is currently running
set_fact:
system_info_debug: true
system_info_plist_path: '{{ansible_env.HOME}}/Library/LaunchAgents/system-info.plist'
system_info_running: "{{'system-info' in launchd_running_services.stdout}}"
system_info_plist_path:
'{{system_info_plist_dir}}/system-info.plist'
system_info_running:
"{{'system-info' in launchd_running_services.stdout}}"
- name: install system-info launchd plist
template:

View File

@@ -0,0 +1,76 @@
---
- name: get latest github release
uri:
url: https://api.github.com/repos/typst/typst/releases/latest
headers: '{{github_auth_headers}}'
register: latest
- set_fact:
asset_name: >-
{{
{
'amd64': 'typst-x86_64-unknown-linux-musl',
'x86_64': 'typst-x86_64-unknown-linux-musl',
'arm64': 'typst-aarch64-unknown-linux-musl',
}[ansible_architecture]
}}
- set_fact:
asset_query: '[?contains(name, `{{asset_name}}.tar.xz`)] | [0]'
assets: '{{latest.json.assets}}'
asset_archive: '{{asset_name}}.tar.xz'
latest_version: '{{latest.json.tag_name}}'
exe: '{{ansible_env.HOME}}/.local/bin/typst'
- name: check if already installed
stat:
path: '{{exe}}'
register: stat_exe
- name: get installed version
when: stat_exe.stat.exists == True
command: '{{exe}} --version'
register: version_output
changed_when: false
- when: stat_exe.stat.exists == True
set_fact:
installed_version:
'v{{version_output.stdout.strip() | regex_replace("^.*(\d+\.\d+\.\d+).*$", "\1")}}'
- set_fact:
asset: '{{assets | to_json | from_json | json_query(asset_query)}}'
- name: download archive
when: installed_version is not defined or installed_version != latest_version
get_url:
url: '{{asset.browser_download_url}}'
dest: '/tmp/{{asset_archive}}'
environment: '{{proxy_environment}}'
- name: extract archive
when: installed_version is not defined or installed_version != latest_version
unarchive:
src: '/tmp/{{asset_archive}}'
dest: '/tmp'
- name: remove archive
when: installed_version is not defined or installed_version != latest_version
file:
state: absent
path: '/tmp/{{asset_archive}}'
- name: copy executable
when: installed_version is not defined or installed_version != latest_version
copy:
src: '/tmp/{{asset_name}}/typst'
dest: '{{exe}}'
mode: +x
- name: remove extraced archive
when: installed_version is not defined or installed_version != latest_version
file:
state: absent
path: '/tmp/{{asset_archive}}'
# TODO: install zsh completions

View File

@@ -0,0 +1,15 @@
---
- name: install homebrew package
when: ansible_os_family == 'Darwin'
homebrew:
state: latest
name: typst
- name: install scoop package
when: ansible_os_family == 'Windows'
community.windows.win_scoop:
state: present
name: typst
- when: ansible_os_family != 'Darwin' and ansible_os_family != 'Windows'
include_tasks: Linux.yaml