├── .chezmoiroot ├── home ├── empty_dot_hushlogin ├── .chezmoiversion ├── dot_local │ ├── share │ │ └── fonts │ │ │ └── .keep │ └── bin │ │ ├── executable_brew-install-version.tmpl │ │ ├── executable_rootmoi.tmpl │ │ ├── executable_kpfd.tmpl │ │ ├── executable_gerrit-clone │ │ ├── executable_full-upgrade.tmpl │ │ ├── executable_pkgs │ │ └── executable_code ├── repos │ └── symlink_dotfiles.tmpl ├── dot_gitignore ├── dot_oh-my-zsh │ └── custom │ │ └── plugins │ │ └── exact_my-completions │ │ ├── empty_my-completions.plugin.zsh │ │ └── _stern.tmpl ├── dot_gerrit-clonerc.json ├── dot_volta │ └── bin │ │ ├── symlink_node.tmpl │ │ ├── symlink_npm.tmpl │ │ ├── symlink_npx.tmpl │ │ ├── symlink_pnpm.tmpl │ │ ├── symlink_yarn.tmpl │ │ └── symlink_devcontainer.tmpl ├── dot_kube │ └── modify_private_config ├── dot_vscode-server │ └── private_data │ │ └── private_Machine │ │ └── modify_settings.json ├── .chezmoitemplates │ ├── get-external-scripts-dir │ ├── get-github-latest-version │ ├── get-github-head-revision │ ├── volta-library │ ├── is-running-with-systemd │ ├── homebrew-library │ ├── remove-files-library │ ├── vscode-library │ └── scripts-library ├── .chezmoidata.yaml ├── .chezmoiscripts │ ├── run_after_90-install-vscode-extensions.sh.tmpl │ ├── run_after_98-prune-chezmoi-binary.sh.tmpl │ ├── run_onchange_after_99-final-message.sh.tmpl │ ├── run_after_80-remove-files.sh.tmpl │ ├── run_after_40-sync-wsl-ssh-keys.sh.tmpl │ ├── run_after_91-install-vscode-extensions-on-windows.sh.tmpl │ ├── run_after_10-initialize-zsh.sh.tmpl │ ├── run_onchange_before_20-upgrade-ca-certificates.sh.tmpl │ ├── run_before_10-migrate.sh.tmpl │ ├── run_after_92-configure-vscode-on-windows.sh.tmpl │ ├── run_after_93-configure-terminal-on-windows.sh.tmpl │ ├── run_after_30-install-pkgx-packages.sh.tmpl │ ├── run_after_31-install-volta-packages.sh.tmpl │ ├── run_onchange_after_86-install-terminal-font-on-windows.sh.tmpl │ ├── run_after_20-run-rootmoi.sh.tmpl │ ├── run_after_82-configure-gnome.sh.tmpl │ ├── run_after_85-install-winget-packages-on-windows.sh.tmpl │ ├── run_after_81-install-gnome-extensions.sh.tmpl │ └── run_after_30-install-homebrew-packages.sh.tmpl ├── modify_dot_gitconfig ├── dot_config │ ├── Code │ │ └── User │ │ │ └── modify_settings.json │ └── rootmoi │ │ └── private_chezmoi.yaml.tmpl ├── dot_bash_profile ├── .chezmoihooks │ └── ensure-pre-requisites.sh ├── .chezmoiignore ├── dot_docker │ └── modify_private_config.json ├── .chezmoiremove ├── dot_bash_aliases.tmpl ├── dot_profile.tmpl ├── .gitconfig.tmpl ├── .chezmoi.yaml.tmpl ├── dot_bashrc ├── dot_zshrc └── .chezmoiexternal.yaml ├── .gitignore ├── .chezmoiignore ├── .github ├── FUNDING.yml ├── dependabot.yaml └── workflows │ └── ci.yaml ├── root ├── .chezmoiversion ├── .chezmoitemplates ├── etc │ ├── ssh │ │ └── sshd_config.d │ │ │ └── custom_sshd_config.conf │ ├── apt │ │ └── sources.list.d │ │ │ ├── modify_google-chrome.list │ │ │ ├── google-chrome-custom.list.tmpl │ │ │ ├── git-core-ppa.list.tmpl │ │ │ ├── wslu-ppa.list.tmpl │ │ │ ├── docker.list.tmpl │ │ │ └── vscode.sources.tmpl │ ├── .gitconfig.tmpl │ ├── modify_gitconfig │ ├── modify_wsl.conf │ └── docker │ │ └── modify_daemon.json ├── .chezmoiscripts │ ├── run_after_90-fix-rootmoi-files-ownership.sh.tmpl │ ├── run_after_30-fix-permissions.sh.tmpl │ ├── run_before_90-restore-permissions.sh.tmpl │ ├── run_onchange_after_96-reload-sshd.sh.tmpl │ ├── run_after_80-remove-files.sh.tmpl │ ├── run_onchange_after_95-restart-docker-daemon.sh.tmpl │ ├── run_after_20-configure-user.sh.tmpl │ ├── run_before_30-uninstall-apt-packages.sh.tmpl │ └── run_after_10-install-apt-packages.sh.tmpl ├── .chezmoiignore ├── usr │ └── local │ │ └── bin │ │ └── executable_git-credential-manager.tmpl ├── .chezmoihooks │ └── ensure-pre-requisites.sh ├── .chezmoiremove └── .chezmoiexternal.yaml ├── docs └── images │ └── create_alternative_chrome_shortcut.gif ├── scripts ├── shellcheck.sh ├── ensure_user_uid.sh ├── install_dotfiles.sh ├── create_alternative_chrome_shortcut.sh └── test.sh ├── .editorconfig ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── .shellcheckrc ├── windows ├── terminal │ ├── modify_settings.json │ └── settings.json └── powershell │ └── Microsoft.PowerShell_profile.ps1 ├── run_migrate.sh ├── LICENSE ├── install.sh └── README.md /.chezmoiroot: -------------------------------------------------------------------------------- 1 | home 2 | -------------------------------------------------------------------------------- /home/empty_dot_hushlogin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | external-scripts/ 2 | -------------------------------------------------------------------------------- /home/.chezmoiversion: -------------------------------------------------------------------------------- 1 | 2.63.0 2 | -------------------------------------------------------------------------------- /home/dot_local/share/fonts/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.chezmoiignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !migrate.sh 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [felipecrs] 2 | -------------------------------------------------------------------------------- /root/.chezmoiversion: -------------------------------------------------------------------------------- 1 | ../home/.chezmoiversion -------------------------------------------------------------------------------- /root/.chezmoitemplates: -------------------------------------------------------------------------------- 1 | ../home/.chezmoitemplates -------------------------------------------------------------------------------- /home/repos/symlink_dotfiles.tmpl: -------------------------------------------------------------------------------- 1 | {{- .chezmoi.workingTree -}} 2 | -------------------------------------------------------------------------------- /home/dot_gitignore: -------------------------------------------------------------------------------- 1 | # misc 2 | *.log 3 | *.tmp 4 | 5 | # direnv 6 | .envrc 7 | -------------------------------------------------------------------------------- /root/etc/ssh/sshd_config.d/custom_sshd_config.conf: -------------------------------------------------------------------------------- 1 | AllowTcpForwarding yes 2 | -------------------------------------------------------------------------------- /home/dot_oh-my-zsh/custom/plugins/exact_my-completions/empty_my-completions.plugin.zsh: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /home/dot_gerrit-clonerc.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultBaseUrl": "https://review.gerrithub.io/a/" 3 | } 4 | -------------------------------------------------------------------------------- /home/dot_volta/bin/symlink_node.tmpl: -------------------------------------------------------------------------------- 1 | {{- joinPath .chezmoi.homeDir ".volta/bin/volta-shim" -}} 2 | -------------------------------------------------------------------------------- /home/dot_volta/bin/symlink_npm.tmpl: -------------------------------------------------------------------------------- 1 | {{- joinPath .chezmoi.homeDir ".volta/bin/volta-shim" -}} 2 | -------------------------------------------------------------------------------- /home/dot_volta/bin/symlink_npx.tmpl: -------------------------------------------------------------------------------- 1 | {{- joinPath .chezmoi.homeDir ".volta/bin/volta-shim" -}} 2 | -------------------------------------------------------------------------------- /home/dot_volta/bin/symlink_pnpm.tmpl: -------------------------------------------------------------------------------- 1 | {{- joinPath .chezmoi.homeDir ".volta/bin/volta-shim" -}} 2 | -------------------------------------------------------------------------------- /home/dot_volta/bin/symlink_yarn.tmpl: -------------------------------------------------------------------------------- 1 | {{- joinPath .chezmoi.homeDir ".volta/bin/volta-shim" -}} 2 | -------------------------------------------------------------------------------- /home/dot_volta/bin/symlink_devcontainer.tmpl: -------------------------------------------------------------------------------- 1 | {{- joinPath .chezmoi.homeDir ".volta/bin/volta-shim" -}} 2 | -------------------------------------------------------------------------------- /home/dot_kube/modify_private_config: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- .chezmoi.stdin -}} 4 | -------------------------------------------------------------------------------- /home/dot_vscode-server/private_data/private_Machine/modify_settings.json: -------------------------------------------------------------------------------- 1 | ../../../dot_config/Code/User/modify_settings.json -------------------------------------------------------------------------------- /home/.chezmoitemplates/get-external-scripts-dir: -------------------------------------------------------------------------------- 1 | {{- joinPath (trimPrefix (print .chezmoi.homeDir "/") .chezmoi.workingTree) "external-scripts" -}} 2 | -------------------------------------------------------------------------------- /home/.chezmoitemplates/get-github-latest-version: -------------------------------------------------------------------------------- 1 | {{- printf "https://github.com/%s/releases/latest" . | getRedirectedURL | base | trimPrefix "v" -}} 2 | -------------------------------------------------------------------------------- /root/etc/apt/sources.list.d/modify_google-chrome.list: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- ensureLinePrefix "#" "# " .chezmoi.stdin -}} 4 | -------------------------------------------------------------------------------- /docs/images/create_alternative_chrome_shortcut.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipecrs/dotfiles/HEAD/docs/images/create_alternative_chrome_shortcut.gif -------------------------------------------------------------------------------- /home/.chezmoitemplates/get-github-head-revision: -------------------------------------------------------------------------------- 1 | {{- printf "https://github.com/%s/raw/HEAD/README.md" . | getRedirectedURL | trimSuffix "/README.md" | base -}} 2 | -------------------------------------------------------------------------------- /scripts/shellcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | exec docker run --rm --interactive --volume="${PWD}:/mnt" --workdir=/mnt koalaman/shellcheck:latest "$@" 4 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | -------------------------------------------------------------------------------- /home/.chezmoidata.yaml: -------------------------------------------------------------------------------- 1 | fontsDir: .local/share/fonts 2 | 3 | terminalFont: 4 | fileName: Fira Code Regular Nerd Font Complete Mono.ttf 5 | name: FiraCode Nerd Font Mono 6 | -------------------------------------------------------------------------------- /root/etc/apt/sources.list.d/google-chrome-custom.list.tmpl: -------------------------------------------------------------------------------- 1 | deb [arch={{ .chezmoi.arch }} signed-by=/usr/share/keyrings/google.asc] https://dl.google.com/linux/chrome/deb/ stable main 2 | -------------------------------------------------------------------------------- /home/.chezmoitemplates/volta-library: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | ensure_path_entry "${HOME}/.volta/bin" 4 | 5 | # https://docs.volta.sh/advanced/pnpm 6 | export VOLTA_FEATURE_PNPM=1 7 | -------------------------------------------------------------------------------- /root/etc/apt/sources.list.d/git-core-ppa.list.tmpl: -------------------------------------------------------------------------------- 1 | deb [signed-by=/usr/share/keyrings/git-core-ppa.asc] http://ppa.launchpad.net/git-core/ppa/ubuntu {{ .chezmoi.osRelease.ubuntuCodename }} main 2 | -------------------------------------------------------------------------------- /root/etc/apt/sources.list.d/wslu-ppa.list.tmpl: -------------------------------------------------------------------------------- 1 | deb [signed-by=/usr/share/keyrings/wslu-ppa.asc] http://ppa.launchpad.net/wslutilities/wslu/ubuntu {{ .chezmoi.osRelease.ubuntuCodename }} main 2 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_after_90-fix-rootmoi-files-ownership.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | chown --recursive '{{ .non_root_user }}' '{{ dir .chezmoi.configFile }}' '{{ .chezmoi.cacheDir }}' 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | end_of_line = lf 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /home/.chezmoitemplates/is-running-with-systemd: -------------------------------------------------------------------------------- 1 | {{- /* Check if system is running with systemd. */ -}} 2 | {{- if eq (output "ps" "--no-headers" "-o" "comm" "1" | trim) "systemd" -}} 3 | true 4 | {{- end -}} 5 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_after_30-fix-permissions.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # After chezmoi finished installing it, we can add execution permission to it. 4 | chmod +x /usr/local/share/gcm/git-credential-manager.exe 5 | -------------------------------------------------------------------------------- /root/etc/apt/sources.list.d/docker.list.tmpl: -------------------------------------------------------------------------------- 1 | deb [arch={{ .chezmoi.arch }} signed-by=/usr/share/keyrings/docker.asc] https://download.docker.com/linux/{{ .chezmoi.osRelease.id }} {{ .chezmoi.osRelease.versionCodename }} stable 2 | -------------------------------------------------------------------------------- /home/dot_oh-my-zsh/custom/plugins/exact_my-completions/_stern.tmpl: -------------------------------------------------------------------------------- 1 | {{- $bin := lookPath (joinPath .chezmoi.homeDir ".deno/bin/stern") | or (lookPath "stern") -}} 2 | {{- if $bin -}} 3 | {{- output $bin "--completion" "zsh" -}} 4 | {{- end -}} 5 | -------------------------------------------------------------------------------- /home/.chezmoitemplates/homebrew-library: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | readonly home_homebrew_prefix="${HOME}/.linuxbrew" 4 | readonly root_homebrew_prefix="/home/linuxbrew/.linuxbrew" 5 | 6 | ensure_path_entry "${home_homebrew_prefix}/bin" "${root_homebrew_prefix}/bin" 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "mads-hartmann.bash-ide-vscode", 4 | "timonwong.shellcheck", 5 | "foxundermoon.shell-format", 6 | "editorconfig.editorconfig", 7 | "ms-kubernetes-tools.vscode-kubernetes-tools", 8 | "tim-koehler.helm-intellisense" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /root/etc/apt/sources.list.d/vscode.sources.tmpl: -------------------------------------------------------------------------------- 1 | ### THIS FILE IS AUTOMATICALLY CONFIGURED ### 2 | # You may comment out this entry, but any other modifications may be lost. 3 | Types: deb 4 | URIs: https://packages.microsoft.com/repos/code 5 | Suites: stable 6 | Components: main 7 | Architectures: {{ .chezmoi.arch }} 8 | Signed-By: /usr/share/keyrings/microsoft.gpg 9 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_before_90-restore-permissions.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # We need to remove execution permission from this file before letting 4 | # chezmoi try to install it. Otherwise, it will identify a difference. 5 | if [[ -x /usr/local/share/gcm/git-credential-manager.exe ]]; then 6 | chmod -x /usr/local/share/gcm/git-credential-manager.exe 7 | fi 8 | -------------------------------------------------------------------------------- /.shellcheckrc: -------------------------------------------------------------------------------- 1 | external-sources=true 2 | # To list all: shellcheck --list-optional 3 | enable=add-default-case 4 | enable=avoid-nullary-conditions 5 | enable=check-extra-masked-returns 6 | enable=check-set-e-suppressed 7 | enable=check-unassigned-uppercase 8 | enable=deprecate-which 9 | enable=quote-safe-variables 10 | enable=require-double-brackets 11 | enable=require-variable-braces 12 | -------------------------------------------------------------------------------- /home/.chezmoitemplates/remove-files-library: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | function remove_files() { 4 | local files_to_remove=() 5 | 6 | for file in "$@"; do 7 | if [[ -f "${file}" ]]; then 8 | files_to_remove+=("${file}") 9 | fi 10 | done 11 | 12 | if [[ ${#files_to_remove[@]} -gt 0 ]]; then 13 | log_task "Removing files" 14 | 15 | c rm -f "${files_to_remove[@]}" 16 | fi 17 | } 18 | -------------------------------------------------------------------------------- /root/etc/.gitconfig.tmpl: -------------------------------------------------------------------------------- 1 | [credential] 2 | helper = /usr/local/bin/git-credential-manager 3 | {{- if .is_wsl }} 4 | credentialStore = wincredman 5 | {{- else if and .is_gnome (not .is_headless) }} 6 | credentialStore = secretservice 7 | {{- else }} 8 | credentialStore = plaintext 9 | {{- end }} 10 | 11 | [filter "lfs"] 12 | clean = git-lfs clean -- %f 13 | smudge = git-lfs smudge -- %f 14 | process = git-lfs filter-process 15 | required = true 16 | -------------------------------------------------------------------------------- /root/etc/modify_gitconfig: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- /* Load existing configuration */ -}} 4 | {{- $result := dict -}} 5 | {{- if not (.chezmoi.stdin | trim | empty) -}} 6 | {{- $result = fromIni .chezmoi.stdin -}} 7 | {{- end -}} 8 | 9 | {{- /* Load default configuration */ -}} 10 | {{- $default := (includeTemplate "etc/.gitconfig.tmpl" . | fromIni) -}} 11 | {{- $result = merge $default $result -}} 12 | 13 | {{- toIni $result -}} 14 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "bashdb", 9 | "request": "launch", 10 | "name": "Bash-Debug (simplest configuration)", 11 | "program": "${file}" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /windows/terminal/modify_settings.json: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- /* Load existing configuration */ -}} 4 | {{- $result := dict -}} 5 | {{- if not (.chezmoi.stdin | trim | empty) -}} 6 | {{- $result = fromJsonc .chezmoi.stdin -}} 7 | {{- end -}} 8 | 9 | {{- /* Set font */ -}} 10 | {{- $result = setValueAtPath "profiles.defaults.font.face" "FiraCode Nerd Font Mono" $result -}} 11 | 12 | {{- toPrettyJson " " $result | trimSuffix "\n" -}} 13 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_90-install-vscode-extensions.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | # {{ template "vscode-library" }} 5 | 6 | # The following line is for ShellCheck to correctly identify the above include 7 | true || source ../.chezmoitemplates/scripts-library 8 | true || source ../.chezmoitemplates/vscode-library 9 | 10 | function code() { 11 | NO_REMOTE=1 command code "$@" 12 | } 13 | 14 | install_vscode_extensions 15 | -------------------------------------------------------------------------------- /root/.chezmoiignore: -------------------------------------------------------------------------------- 1 | {{ if not .is_gnome }} 2 | etc/apt/sources.list.d/vscode-custom.list 3 | etc/apt/sources.list.d/google-chrome-custom.list 4 | etc/apt/sources.list.d/vscode.sources 5 | etc/apt/sources.list.d/google-chrome.list 6 | {{ end }} 7 | 8 | {{ if .is_wsl }} 9 | etc/ssh 10 | .chezmoiscripts/*-reload-sshd.sh 11 | {{ else }} 12 | etc/wsl.conf 13 | etc/apt/sources.list.d/wslu-ppa.list 14 | .chezmoiscripts/*-fix-permissions.sh 15 | .chezmoiscripts/*-restore-permissions.sh 16 | {{ end }} 17 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_98-prune-chezmoi-binary.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | chezmoi_executable="{{ .chezmoi.executable }}" 9 | if [[ "${chezmoi_executable}" != *"/.linuxbrew/"* ]]; then 10 | log_task "Uninstalling chezmoi not installed by Homebrew: ${chezmoi_executable}" 11 | rm -f "${chezmoi_executable}" 12 | fi 13 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_onchange_after_96-reload-sshd.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | # custom_sshd_config.conf hash: {{ include "/etc/ssh/sshd_config.d/custom_sshd_config.conf" | sha256sum }} 9 | 10 | if service_exists ssh; then 11 | log_task "Reloading SSH daemon" 12 | c systemctl try-reload-or-restart ssh 13 | fi 14 | -------------------------------------------------------------------------------- /root/etc/modify_wsl.conf: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- /* Load existing configuration */ -}} 4 | {{- $result := dict -}} 5 | {{- if not (.chezmoi.stdin | trim | empty) -}} 6 | {{- $result = fromIni .chezmoi.stdin -}} 7 | {{- end -}} 8 | 9 | {{- /* Enable systemd */ -}} 10 | {{- $result = setValueAtPath "boot.systemd" true $result -}} 11 | 12 | {{- /* If there is no output, chezmoi deletes the file */ -}} 13 | {{- $result = pruneEmptyDicts $result -}} 14 | {{- if not (empty $result) -}} 15 | {{- toIni $result -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /home/modify_dot_gitconfig: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- /* Load existing configuration */ -}} 4 | {{- $result := dict -}} 5 | {{- if not (.chezmoi.stdin | trim | empty) -}} 6 | {{- $result = fromIni .chezmoi.stdin -}} 7 | {{- end -}} 8 | 9 | {{- /* Delete alias.rr as it is renamed to alias.rhu */ -}} 10 | {{- $result = deleteValueAtPath "alias.rr" $result -}} 11 | 12 | {{- /* Load default configuration */ -}} 13 | {{- $default := (includeTemplate ".gitconfig.tmpl" . | fromIni) -}} 14 | {{- $result = merge $default $result -}} 15 | 16 | {{- toIni $result -}} 17 | -------------------------------------------------------------------------------- /home/dot_config/Code/User/modify_settings.json: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- /* Load existing configuration */ -}} 4 | {{- $result := dict -}} 5 | {{- if not (.chezmoi.stdin | trim | empty) -}} 6 | {{- $result = fromJsonc .chezmoi.stdin -}} 7 | {{- end -}} 8 | 9 | {{- /* Set terminal font */ -}} 10 | {{- $result = setValueAtPath (list "terminal.integrated.fontFamily") "FiraCode Nerd Font Mono" $result -}} 11 | 12 | {{- /* Fix Linux title bars */ -}} 13 | {{- $result = setValueAtPath (list "window.titleBarStyle") "custom" $result -}} 14 | 15 | {{- toPrettyJson " " $result | trimSuffix "\n" -}} 16 | -------------------------------------------------------------------------------- /root/usr/local/bin/executable_git-credential-manager.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | # {{ if .is_wsl }} 6 | # Running the Windows version of Git Credential Manager requires 7 | # these additional environment variables as per: 8 | # https://github.com/GitCredentialManager/git-credential-manager/issues/376 9 | GIT_EXEC_PATH="$(git --exec-path)" 10 | export GIT_EXEC_PATH 11 | export WSLENV="${WSLENV}:GIT_EXEC_PATH/wp" 12 | # shellcheck disable=SC2093 13 | exec /usr/local/share/gcm/git-credential-manager.exe "${@}" 14 | # {{ else }} 15 | exec /usr/local/share/gcm/git-credential-manager "${@}" 16 | # {{ end }} 17 | -------------------------------------------------------------------------------- /root/etc/docker/modify_daemon.json: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- /* Load existing configuration */ -}} 4 | {{- $result := dict -}} 5 | {{- if not (.chezmoi.stdin | trim | empty) -}} 6 | {{- $result = fromJson .chezmoi.stdin -}} 7 | {{- end -}} 8 | 9 | {{- /* Delete features.buildkit as it is now the default */ -}} 10 | {{- $result = deleteValueAtPath "features.buildkit" $result -}} 11 | 12 | {{- /* If there is no output, chezmoi deletes the file */ -}} 13 | {{- $result = pruneEmptyDicts $result -}} 14 | {{- if not (empty $result) -}} 15 | {{- toPrettyJson "\t" $result | trimSuffix "\n" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /home/dot_bash_profile: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # Bash does not source .profile when .bash_profile is found so we do it here 4 | # https://stackoverflow.com/a/9954208/12156188 5 | if [[ -r "${HOME}/.profile" ]]; then 6 | # shellcheck source=./dot_profile.tmpl 7 | source "${HOME}/.profile" 8 | fi 9 | 10 | # if not coming from .bashrc and .bashrc exists 11 | # https://stackoverflow.com/a/9954208/12156188 12 | if [[ -z "${COMING_FROM_BASHRC}" && -r "${HOME}/.bashrc" ]]; then 13 | export COMING_FROM_BASH_PROFILE=true 14 | # shellcheck source=./dot_bashrc 15 | source "${HOME}/.bashrc" 16 | unset COMING_FROM_BASH_PROFILE 17 | fi 18 | -------------------------------------------------------------------------------- /home/dot_config/rootmoi/private_chezmoi.yaml.tmpl: -------------------------------------------------------------------------------- 1 | {{- $chezmoiData := deepCopy . -}} 2 | {{- $chezmoiData = unset $chezmoiData "chezmoi" -}} 3 | 4 | {{- $sourceDir := joinPath .chezmoi.workingTree "root" -}} 5 | sourceDir: "{{ $sourceDir }}" 6 | 7 | destDir: "/" 8 | 9 | verbose: true 10 | 11 | # https://github.com/twpayne/chezmoi/issues/3257 12 | pager: "" 13 | 14 | diff: 15 | exclude: 16 | - scripts 17 | status: 18 | exclude: 19 | - always 20 | 21 | hooks: 22 | read-source-state: 23 | pre: 24 | command: {{ $sourceDir }}/.chezmoihooks/ensure-pre-requisites.sh 25 | 26 | data: 27 | non_root_user: "{{ .chezmoi.username }}" 28 | {{- $chezmoiData | toYaml | nindent 2 }} 29 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_after_80-remove-files.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | # {{ template "remove-files-library" }} 5 | 6 | # The following line is for ShellCheck to correctly identify the above included library 7 | true || source ../.chezmoitemplates/scripts-library 8 | true || source ../.chezmoitemplates/remove-files-library 9 | 10 | # This is a workaround for the following issue: 11 | # https://github.com/twpayne/chezmoi/discussions/1789#discussioncomment-1920082 12 | 13 | readonly unwanted_files=( 14 | # {{ if not .is_gnome }} 15 | /usr/bin/docker-credential-secretservice 16 | # {{ end }} 17 | ) 18 | 19 | remove_files "${unwanted_files[@]}" 20 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_onchange_after_99-final-message.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ include (joinPath .chezmoi.sourceDir ".chezmoitemplates/scripts-library") }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | log_green "✅ Dotfiles installation finished successfully" 9 | 10 | # {{ if .is_gnome }} 11 | log_info "If this is a first time installation, please logout and log back in" "to get started. You can temporarily preview the changes by running:" 12 | # {{ else }} 13 | log_info "If this is a first time installation, get started by running:" 14 | # {{ end }} 15 | log_c "exec zsh" 16 | -------------------------------------------------------------------------------- /run_migrate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # This script will only be run if chezmoi is older than 2.9.1, 4 | # because otherwise the .chezmoiroot file will be honored. 5 | 6 | set -euo pipefail 7 | 8 | function log_color() { 9 | local color_code="$1" 10 | shift 11 | 12 | printf "\033[${color_code}m%s\033[0m\n" "$*" >&2 13 | } 14 | 15 | function log_red() { 16 | log_color "0;31" "$@" 17 | } 18 | 19 | function log_error() { 20 | log_red "❌" "$@" 21 | } 22 | 23 | function error() { 24 | log_error "$@" 25 | exit 1 26 | } 27 | 28 | error " 29 | ⚠️ Detected old chezmoi version 30 | 31 | ❌ Manual action needed. To continue, please run: 32 | 33 | 👉 brew upgrade chezmoi && chezmoi init --apply 34 | " 35 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_80-remove-files.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | # {{ template "remove-files-library" }} 5 | 6 | # The following line is for ShellCheck to correctly identify the above included library 7 | true || source ../.chezmoitemplates/scripts-library 8 | true || source ../.chezmoitemplates/remove-files-library 9 | 10 | # This is a workaround for the following issue: 11 | # https://github.com/twpayne/chezmoi/discussions/1789#discussioncomment-1920082 12 | 13 | readonly unwanted_files=( 14 | # {{ if not .is_gnome }} 15 | "{{ .chezmoi.homeDir }}/.local/bin/gnome-shell-extension-installer" 16 | # {{ end }} 17 | ) 18 | 19 | remove_files "${unwanted_files[@]}" 20 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_onchange_after_95-restart-docker-daemon.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | # {{ if stat "/etc/docker/daemon.json" }} 9 | # daemon.json hash: {{ include "/etc/docker/daemon.json" | sha256sum }} 10 | # {{ end }} 11 | 12 | log_task "Restarting Docker daemon" 13 | # {{ if and .is_wsl (not (includeTemplate "is-running-with-systemd" .)) }} 14 | # service restart fails if the service was never started 15 | c service docker restart || not_during_test c service docker start 16 | # {{ else }} 17 | c systemctl restart docker 18 | # {{ end }} 19 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_40-sync-wsl-ssh-keys.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | win_home="$(wslvar USERPROFILE)" 9 | win_home="$(wslpath "${win_home}")" 10 | 11 | # The .nomedia file is created automatically by WSA with weird permissions that rsync can't handle 12 | rsync_cmd=(rsync --chmod=F600 --archive --delete --itemize-changes --checksum --exclude .nomedia "${win_home}/.ssh/" "${HOME}/.ssh/") 13 | 14 | if [[ -f "${win_home}/.ssh/id_rsa" ]] && "${rsync_cmd[@]}" --dry-run | grep --quiet .; then 15 | log_task "Syncing .ssh folder from Windows to WSL" 16 | "${rsync_cmd[@]}" 17 | fi 18 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | jobs: 10 | test: 11 | strategy: 12 | fail-fast: false 13 | matrix: 14 | variant: [devcontainer, wsl, gnome] 15 | os: [ubuntu-20.04, ubuntu-22.04, ubuntu-24.04] 16 | include: 17 | - variant: devcontainer 18 | os: alpine 19 | - variant: devcontainer 20 | os: debian 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v6 24 | - run: | 25 | scripts/test.sh --variant "${{ matrix.variant }}" --os "${{ matrix.os }}" 26 | verdict: 27 | needs: test 28 | runs-on: ubuntu-latest 29 | steps: 30 | - run: echo "All tests passed!" 31 | -------------------------------------------------------------------------------- /home/.chezmoitemplates/vscode-library: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | wanted_extensions=( 4 | ms-vscode-remote.vscode-remote-extensionpack 5 | ) 6 | 7 | function is_vscode_extension_installed() { 8 | local extension="$1" 9 | 10 | # shellcheck disable=SC2312 11 | code --list-extensions 2>/dev/null | grep "${extension}" >/dev/null 12 | } 13 | 14 | function install_vscode_extensions() { 15 | for extension in "${wanted_extensions[@]}"; do 16 | if ! is_vscode_extension_installed "${extension}"; then 17 | if [[ -n "${FOR_WINDOWS:-}" ]]; then 18 | log_task "Installing VS Code extension on Windows: ${extension}" 19 | else 20 | log_task "Installing VS Code extension: ${extension}" 21 | fi 22 | c code --install-extension "${extension}" 23 | fi 24 | done 25 | } 26 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_after_20-configure-user.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | # Configure passwordless sudo 9 | file='/etc/sudoers.d/{{ .non_root_user }}' 10 | file_contents='{{ .non_root_user }} ALL=(ALL) NOPASSWD:ALL' 11 | if [[ ! -f "${file}" ]] || ! grep -q "${file_contents}" "${file}"; then 12 | log_task 'Configuring passwordless sudo for {{ .non_root_user }}' 13 | echo "${file_contents}" >"${file}" 14 | fi 15 | unset file file_contents 16 | 17 | # shellcheck disable=SC2312 18 | if ! getent group docker | grep -q '\b{{ .non_root_user }}\b'; then 19 | log_task 'Adding {{ .non_root_user }} to docker group' 20 | usermod -aG docker '{{ .non_root_user }}' 21 | fi 22 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_before_30-uninstall-apt-packages.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ include (joinPath .chezmoi.sourceDir ".chezmoitemplates/scripts-library") }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | readonly unwanted_packages=( 9 | gcmcore 10 | direnv 11 | crudini 12 | fzf 13 | # It is now installed as a chezmoiexternal 14 | skopeo 15 | # It is deprecated 16 | docker-scan-plugin 17 | # It is now installed as a chezmoiexternal 18 | pipx 19 | ) 20 | 21 | for package in "${unwanted_packages[@]}"; do 22 | # shellcheck disable=SC2310 23 | if is_apt_package_installed "${package}"; then 24 | log_task "Removing unwanted package '${package}' installed with APT" 25 | c env DEBIAN_FRONTEND=noninteractive apt remove --yes --auto-remove "${package}" 26 | fi 27 | done 28 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_91-install-vscode-extensions-on-windows.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | # {{ template "vscode-library" }} 5 | 6 | # The following line is for ShellCheck to correctly identify the above include 7 | true || source ../.chezmoitemplates/scripts-library 8 | true || source ../.chezmoitemplates/vscode-library 9 | 10 | function code() { 11 | local script 12 | script=$( 13 | cat </dev/null && [[ ! -d "${HOME}/.cache/gitstatus" ]]; then 18 | log_task "Initializing ZSH" 19 | bash -e <<'EOF' >/dev/null 20 | # We need to be in a git repository, so gitstatusd initiliazes 21 | cd '{{ .chezmoi.workingTree }}' 22 | 23 | # We also need to emulate a TTY 24 | script -qec "zsh -is /dev/null; then 17 | missing_packages+=("${package}") 18 | fi 19 | done 20 | 21 | if [[ ${#missing_packages[@]} -eq 0 ]]; then 22 | exit 0 23 | fi 24 | 25 | # shellcheck source=../.chezmoitemplates/scripts-library 26 | source "${CHEZMOI_SOURCE_DIR?}/.chezmoitemplates/scripts-library" 27 | 28 | log_task "Installing missing pre-requisites with APT: ${missing_packages[*]}" 29 | 30 | c apt update 31 | c env DEBIAN_FRONTEND=noninteractive apt install --yes --no-install-recommends "${missing_packages[@]}" 32 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_onchange_before_20-upgrade-ca-certificates.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # We need to install ca-certificates before we add the APT repos, because some of them 4 | # may use newer CAs. 5 | 6 | # {{ include (joinPath .chezmoi.sourceDir ".chezmoitemplates/scripts-library") }} 7 | 8 | # The following line is for ShellCheck to correctly identify the above included library 9 | true || source ../.chezmoitemplates/scripts-library 10 | 11 | log_task "Upgrading ca-certificates" 12 | 13 | # Ignore apt update error if it is due to expired certificate (because chances 14 | # are that the next command will fix it). 15 | # shellcheck disable=SC2310 16 | if output="$(c sudo apt update)" || [[ "${output}" == *"The certificate chain uses expired certificate."* ]]; then 17 | echo "${output}" 18 | true 19 | else 20 | echo "${output}" 21 | exit 1 22 | fi 23 | 24 | c sudo env DEBIAN_FRONTEND=noninteractive apt install --yes --no-install-recommends ca-certificates 25 | -------------------------------------------------------------------------------- /home/.chezmoihooks/ensure-pre-requisites.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script must exit as fast as possible when pre-requisites are already 4 | # met, so we only import the scripts-library when we really need it. 5 | 6 | set -eu 7 | 8 | wanted_packages=( 9 | git # used to find the latest revisions of github repositories 10 | curl # used to find the latest version of github repositories 11 | zsh 12 | ) 13 | 14 | missing_packages=() 15 | 16 | for package in "${wanted_packages[@]}"; do 17 | if ! command -v "${package}" >/dev/null; then 18 | missing_packages+=("${package}") 19 | fi 20 | done 21 | 22 | if [[ ${#missing_packages[@]} -eq 0 ]]; then 23 | exit 0 24 | fi 25 | 26 | # shellcheck source=../.chezmoitemplates/scripts-library 27 | source "${CHEZMOI_SOURCE_DIR?}/.chezmoitemplates/scripts-library" 28 | 29 | log_task "Installing missing packages with APT: ${missing_packages[*]}" 30 | 31 | c sudo apt update 32 | c sudo env DEBIAN_FRONTEND=noninteractive apt install --yes --no-install-recommends "${missing_packages[@]}" 33 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_before_10-migrate.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script is executed every time chezmoi apply is run, before 4 | # anything else. It is meant for handling the migration of data 5 | # which cannot be managed by chezmoi itself. 6 | 7 | # {{ include (joinPath .chezmoi.sourceDir ".chezmoitemplates/scripts-library") }} 8 | 9 | # The following line is for ShellCheck to correctly identify the above included library 10 | true || source ../.chezmoitemplates/scripts-library 11 | 12 | migrated=false 13 | 14 | # Migrate from .chezmoi.toml.tmpl to chezmoi.yaml.tmpl 15 | # {{ if and (stat .chezmoi.configFile) (not (hasSuffix ".yaml" .chezmoi.configFile)) }} 16 | log_red "⚠️ Detected old configuration file at '{{ .chezmoi.configFile }}'. Deleting it..." 17 | rm -f "{{ .chezmoi.configFile }}" 18 | migrated=true 19 | # {{ end }} 20 | 21 | if [[ "${migrated}" == true ]]; then 22 | error " 23 | ❌ Manual action needed. To continue, please run: 24 | 25 | 👉 chezmoi init --source '{{ .chezmoi.workingTree }}' && chezmoi apply --force 26 | " 27 | fi 28 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_92-configure-vscode-on-windows.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | settings_dir="$(wslvar APPDATA)" 9 | settings_dir="$(wslpath "${settings_dir}")" 10 | settings_dir="${settings_dir}/Code/User" 11 | 12 | settings_path="${settings_dir}/settings.json" 13 | if [[ -f "${settings_path}" ]]; then 14 | settings="$(cat "${settings_path}")" 15 | else 16 | settings='' 17 | fi 18 | 19 | template_path='{{ joinPath .chezmoi.sourceDir "dot_config/Code/User/modify_settings.json" }}' 20 | template="$(cat "${template_path}")" 21 | 22 | chezmoi_path='{{ .chezmoi.executable }}' 23 | 24 | result="$("${chezmoi_path}" execute-template --with-stdin "${template}" <<<"${settings}")" 25 | 26 | if [[ "${result}" != "${settings}" ]]; then 27 | log_task "Configuring VS Code on Windows" 28 | mkdir -p "${settings_dir}" 29 | tee "${settings_path}" >/dev/null <<<"${result}" 30 | fi 31 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_93-configure-terminal-on-windows.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | win_home="$(wslvar USERPROFILE)" 9 | settings_dir="$(wslpath "${win_home}\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState")" 10 | settings_path="${settings_dir}/settings.json" 11 | if [[ -f "${settings_path}" ]]; then 12 | settings="$(cat "${settings_path}")" 13 | else 14 | settings='' 15 | fi 16 | 17 | template_path='{{ joinPath .chezmoi.workingTree "windows/terminal/modify_settings.json" }}' 18 | template="$(cat "${template_path}")" 19 | 20 | chezmoi_path='{{ .chezmoi.executable }}' 21 | 22 | result="$("${chezmoi_path}" execute-template --with-stdin "${template}" <<<"${settings}")" 23 | 24 | if [[ "${result}" != "${settings}" ]]; then 25 | log_task "Configuring Terminal on Windows" 26 | mkdir -p "${settings_dir}" 27 | tee "${settings_path}" >/dev/null <<<"${result}" 28 | fi 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Felipe Santos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_30-install-pkgx-packages.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | ensure_path_entry "${HOME}/.local/bin" 9 | 10 | readonly unwanted_packages=() 11 | 12 | for package in "${unwanted_packages[@]}"; do 13 | if pkgs installed "${package}" >/dev/null; then 14 | log_task "Removing unwanted package '${package}' installed with pkgx" 15 | pkgs uninstall "${package}" 16 | fi 17 | done 18 | 19 | readonly wanted_packages=( 20 | opendev.org/git-review 21 | # {{ if not .is_devcontainer }} 22 | openjdk.org 23 | maven.apache.org 24 | # {{ end }} 25 | ) 26 | 27 | missing_packages=() 28 | 29 | for package in "${wanted_packages[@]}"; do 30 | if ! pkgs installed "${package}" >/dev/null; then 31 | missing_packages+=("${package}") 32 | fi 33 | done 34 | 35 | if [[ ${#missing_packages[@]} -gt 0 ]]; then 36 | log_task "Installing missing packages with pkgx: ${missing_packages[*]}" 37 | pkgs install "${missing_packages[@]}" 38 | fi 39 | -------------------------------------------------------------------------------- /home/.chezmoiignore: -------------------------------------------------------------------------------- 1 | {{ if .is_devcontainer -}} 2 | .local/bin/code 3 | .volta/bin 4 | 5 | .chezmoiscripts/* 6 | !.chezmoiscripts/*-initialize-zsh.sh 7 | !.chezmoiscripts/*-final-message.sh 8 | {{ if ne .chezmoi.osRelease.id "alpine" -}} 9 | !.chezmoiscripts/*-install-pkgx-packages.sh 10 | {{- end }} 11 | {{- end }} 12 | 13 | {{ if not .is_gnome -}} 14 | .chezmoiscripts/*-install-gnome-extensions.sh 15 | .chezmoiscripts/*-configure-gnome.sh 16 | .chezmoiscripts/*-install-vscode-extensions.sh 17 | .config/Code/User/settings.json 18 | {{- end }} 19 | 20 | {{ if not .is_wsl -}} 21 | .chezmoiscripts/*-sync-wsl-ssh-keys.sh 22 | .chezmoiscripts/*-install-winget-packages-on-windows.sh 23 | .chezmoiscripts/*-install-terminal-font-on-windows.sh 24 | .chezmoiscripts/*-configure-vscode-on-windows.sh 25 | .chezmoiscripts/*-configure-terminal-on-windows.sh 26 | .chezmoiscripts/*-install-vscode-extensions-on-windows.sh 27 | {{- else -}} 28 | .chezmoiscripts/*-install-gnome-extensions.sh 29 | {{- end }} 30 | 31 | # waiting for chezmoi to leverage .gitignore from archives: 32 | # https://github.com/twpayne/chezmoi/issues/1421#issuecomment-964473844 33 | .oh-my-zsh/cache/* 34 | **/*.zwc 35 | -------------------------------------------------------------------------------- /home/dot_docker/modify_private_config.json: -------------------------------------------------------------------------------- 1 | {{- /* chezmoi:modify-template */ -}} 2 | 3 | {{- /* Load existing configuration */ -}} 4 | {{- $result := dict -}} 5 | {{- if not (.chezmoi.stdin | trim | empty) -}} 6 | {{- $result = fromJson .chezmoi.stdin -}} 7 | {{- end -}} 8 | 9 | {{- /* Delete features.buildkit as it is now the default */ -}} 10 | {{- $result = deleteValueAtPath "features.buildkit" $result -}} 11 | 12 | {{- /* Delete aliases.builder=buildx as it is now the default */ -}} 13 | {{- $result = deleteValueAtPath "aliases.builder" $result -}} 14 | 15 | {{- /* Set credentials helper */ -}} 16 | {{- $keyName := "credsStore" -}} 17 | {{- if .is_wsl -}} 18 | {{- $result = setValueAtPath $keyName "wincred.exe" $result -}} 19 | {{- else if and .is_gnome (not .is_headless) -}} 20 | {{- $result = setValueAtPath $keyName "secretservice" $result -}} 21 | {{- else -}} 22 | {{- $result = deleteValueAtPath $keyName $result -}} 23 | {{- end -}} 24 | 25 | {{- /* If there is no output, chezmoi deletes the file */ -}} 26 | {{- $result = pruneEmptyDicts $result -}} 27 | {{- if not (empty $result) -}} 28 | {{- toPrettyJson "\t" $result | trimSuffix "\n" -}} 29 | {{- end -}} 30 | -------------------------------------------------------------------------------- /home/dot_local/bin/executable_brew-install-version.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../../.chezmoitemplates/scripts-library 7 | 8 | readonly formula="$1" 9 | readonly version="$2" 10 | 11 | homebrew_core_dir="$(brew --prefix)/Homebrew/Library/Taps/homebrew/homebrew-core" 12 | 13 | export HOMEBREW_NO_INSTALL_FROM_API=1 14 | export HOMEBREW_NO_AUTO_UPDATE=1 15 | export HOMEBREW_NO_UPDATE_REPORT_NEW=1 16 | export HOMEBREW_NO_ENV_HINTS=1 17 | 18 | if [[ ! -d "${homebrew_core_dir}" ]]; then 19 | c brew tap homebrew/core 20 | fi 21 | 22 | c brew update --force 23 | 24 | formula_file="$(brew info "${formula}" | grep --only-matching "Formula/.*.rb")" 25 | 26 | revision=$(c git -C "${homebrew_core_dir}" log --grep "${version}" -1 --pretty=format:"%H" -- "${formula_file}") 27 | 28 | if [[ -z "${revision}" ]]; then 29 | error "No revision found for formula '${formula}' with version '${version}'" 30 | fi 31 | 32 | c git -C "${homebrew_core_dir}" reset --hard "${revision}" 33 | 34 | if brew list "${formula}" &>/dev/null; then 35 | c brew uninstall --force "${formula}" 36 | fi 37 | 38 | c exec brew install --force "${formula}" 39 | -------------------------------------------------------------------------------- /root/.chezmoiremove: -------------------------------------------------------------------------------- 1 | etc/apt/sources.list.d/git-core-ubuntu-ppa-*.list* 2 | etc/apt/sources.list.d/communitheme-ubuntu-ppa-*.list* 3 | etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list* 4 | 5 | # We no longer use the kubic repository 6 | etc/apt/sources.list.d/kubic.list 7 | usr/share/keyrings/kubic-archive-keyring.gpg 8 | 9 | # GCM Core got renamed to GCM only 10 | usr/local/bin/git-credential-manager-core 11 | usr/local/share/gcm-core 12 | 13 | # Migrated to vscode.sources 14 | etc/apt/sources.list.d/vscode.list 15 | 16 | # Migrated to .asc 17 | usr/share/keyrings/docker-archive-keyring.gpg 18 | usr/share/keyrings/git-core-ppa-archive-keyring.gpg 19 | usr/share/keyrings/wslu-ppa-archive-keyring.gpg 20 | usr/share/keyrings/vscode-archive-keyring.gpg 21 | usr/share/keyrings/google-chrome-archive-keyring.gpg 22 | 23 | # https://github.com/microsoft/vscode/issues/255581 24 | etc/apt/sources.list.d/vscode-custom.list 25 | usr/share/keyrings/microsoft.asc 26 | 27 | # These files are known to be installed by Docker Desktop and they 28 | # conflict with the ones installed by APT. 29 | usr/local/lib/docker/cli-plugins/docker-buildx 30 | usr/local/lib/docker/cli-plugins/docker-compose 31 | usr/local/lib/docker/cli-plugins/docker-scan 32 | 33 | # No longer used 34 | {{ joinPath (.chezmoi.cacheDir | trimPrefix .chezmoi.homeDir | trimPrefix "/") "external/versions_and_revisions.yaml" }} 35 | -------------------------------------------------------------------------------- /home/.chezmoiremove: -------------------------------------------------------------------------------- 1 | {{- if not .is_devcontainer -}} 2 | 3 | *.deb 4 | *.rpm 5 | *.tar 6 | *.tar.gz 7 | *.tar.xz 8 | *.tgz 9 | *.zip 10 | 11 | .local/bin/localpath 12 | 13 | .local/bin/docker 14 | 15 | # These files are now installed to system-wide 16 | .local/bin/docker-compose 17 | .local/bin/docker-credential-wincred.exe 18 | .local/bin/docker-credential-secretservice 19 | 20 | # use werf helm upgrade --wait instead 21 | .local/bin/helm-upgrade-logs 22 | 23 | # use pkgx argbash instead, easy enough 24 | .local/bin/argbash 25 | .local/bin/argbash-init 26 | 27 | # now we use gext instead 28 | .local/bin/gnome-shell-extension-installer 29 | 30 | # now we use uv instead 31 | .local/bin/pipx 32 | .local/share/pipx 33 | 34 | # tea got renamed to pkgx 35 | .local/bin/tea 36 | .tea 37 | 38 | .docker/cli-plugins/docker-compose 39 | .docker/cli-plugins/docker-buildx 40 | 41 | .antigen/ 42 | .antigenrc 43 | 44 | # pkgx can be used instead 45 | .sdkman/ 46 | 47 | # Remove font variants there used to be installed but no longer are 48 | .local/share/fonts/Fira Code * Nerd Font Complete*.ttf 49 | !.local/share/fonts/Fira Code Regular Nerd Font Complete Mono.ttf 50 | 51 | # Now using oh-my-zsh plugins 52 | .oh-my-zsh/custom/plugins/my-completions/_deno 53 | .oh-my-zsh/custom/plugins/my-completions/_volta 54 | 55 | # No longer used 56 | {{ joinPath (.chezmoi.cacheDir | trimPrefix .chezmoi.homeDir | trimPrefix "/") "external/versions_and_revisions.yaml" }} 57 | {{- end -}} 58 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_31-install-volta-packages.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | # {{ template "volta-library" }} 5 | 6 | # The following line is for ShellCheck to correctly identify the above include 7 | true || source ../.chezmoitemplates/scripts-library 8 | true || source ../.chezmoitemplates/volta-library 9 | 10 | function is_volta_package_installed() { 11 | local package="$1" 12 | 13 | volta list --current --quiet --format plain "${package}" | grep --quiet . 14 | } 15 | 16 | readonly unwanted_packages=( 17 | @vscode/dev-container-cli 18 | ) 19 | 20 | for package in "${unwanted_packages[@]}"; do 21 | # shellcheck disable=SC2310 22 | if is_volta_package_installed "${package}"; then 23 | log_task "Removing unwanted packages with Volta: ${missing_packages[*]}" 24 | volta uninstall "${package}" 25 | fi 26 | done 27 | 28 | readonly wanted_packages=( 29 | node 30 | npm 31 | yarn 32 | pnpm 33 | @devcontainers/cli 34 | ) 35 | 36 | missing_packages=() 37 | 38 | for package in "${wanted_packages[@]}"; do 39 | # shellcheck disable=SC2310 40 | if ! is_volta_package_installed "${package}"; then 41 | missing_packages+=("${package}") 42 | fi 43 | done 44 | 45 | if [[ ${#missing_packages[@]} -gt 0 ]]; then 46 | log_task "Installing missing packages with Volta: ${missing_packages[*]}" 47 | # https://github.com/volta-cli/volta/issues/1523#issuecomment-1701844815 48 | ensure_path_entry "${HOME}/.local/bin" 49 | retry --tries 9 --sleep 15s -- \ 50 | volta install "${missing_packages[@]}" 51 | fi 52 | -------------------------------------------------------------------------------- /home/dot_bash_aliases.tmpl: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | # This file is automatically sourced by bash, and it's also sourced in .zshrc 4 | # in order to keep the same aliases on both shells. So keep in mind that any 5 | # code here must be compatible with bash and zsh. 6 | 7 | if command -v kubectl >/dev/null && command -v kubecolor >/dev/null; then 8 | alias kubectl="kubecolor" 9 | fi 10 | 11 | refreshenv() { 12 | local shell 13 | 14 | shell=$(ps -p $$ -ocomm=) && 15 | exec "${shell}" 16 | } 17 | 18 | mcd() { 19 | local dir="$1" 20 | 21 | mkdir -p "${dir}" && 22 | cd "${dir}" 23 | } 24 | 25 | cdr() { 26 | local repo="${1:-}" 27 | 28 | cd "${HOME}/repos/${repo}" 29 | } 30 | 31 | # See: https://github.com/twpayne/chezmoi/issues/854#issuecomment-675160348 32 | chezmoi-re-run-scripts() { ( 33 | set -ex 34 | 35 | rm -f "${HOME}/.config/chezmoi/chezmoistate.boltdb" 36 | chezmoi init --apply 37 | ); } 38 | 39 | # Merge all ~/.kube/*.kubeconfig.yaml into ~/.kube/config 40 | merge-kubeconfigs() { 41 | # shellcheck disable=SC2312 42 | KUBECONFIG="$(printf '%s:' "${HOME}"/.kube/*.kubeconfig.yaml | sed 's/:$//')" kubectl config view --flatten | tee "${HOME}/.kube/config" 43 | } 44 | 45 | # {{ if .is_wsl }} 46 | gsudo() { 47 | local shell 48 | 49 | shell=$(ps -p $$ -ocomm=) && 50 | gsudo.exe wsl -d "${WSL_DISTRO_NAME?}" -e "${shell}" "-c" "$*" 51 | } 52 | 53 | cdw() { 54 | local user_profile 55 | local win_home 56 | 57 | user_profile=$(wslvar USERPROFILE) && 58 | win_home=$(wslpath "${user_profile}") && 59 | cd "${win_home}" 60 | } 61 | # {{ end }} 62 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_onchange_after_86-install-terminal-font-on-windows.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | # {{ $fontPath := joinPath .chezmoi.homeDir .fontsDir .terminalFont.fileName }} 9 | # {{ $externalScriptsDir := joinPath .chezmoi.homeDir (includeTemplate "get-external-scripts-dir" .) }} 10 | # {{ $installFontPs1Path := joinPath $externalScriptsDir "Install-Font.ps1" }} 11 | # The Uninstall-Font.ps1 is used by Install-Font.ps1 12 | # {{ $uninstallFontPs1Path := joinPath $externalScriptsDir "Uninstall-Font.ps1" }} 13 | 14 | # hashes: 15 | # {{ include $fontPath | sha256sum }} 16 | # {{ include $installFontPs1Path | sha256sum }} 17 | # {{ include $uninstallFontPs1Path | sha256sum }} 18 | 19 | # shellcheck disable=SC2016 20 | font_path_for_win="$(wslpath -w '{{ $fontPath }}')" 21 | 22 | # shellcheck disable=SC2016 23 | install_font_ps1_path='{{ $installFontPs1Path }}' 24 | install_font_ps1_path_for_win="$(wslpath -w "${install_font_ps1_path}")" 25 | 26 | log_task "Installing terminal font '{{ .terminalFont.name }}' on Windows" 27 | 28 | log_manual_action "If this is the first time installing the font, please restart Windows Terminal and VS Code to ensure they recognize the font" 29 | 30 | not_during_test c PowerShell.exe -NoProfile -ExecutionPolicy Bypass \ 31 | -File "${install_font_ps1_path_for_win}" \ 32 | -Path "${font_path_for_win}" \ 33 | -Scope User \ 34 | -Method Manual \ 35 | -UninstallExisting 36 | -------------------------------------------------------------------------------- /home/dot_profile.tmpl: -------------------------------------------------------------------------------- 1 | # shellcheck shell=sh 2 | # chezmoi:template:left-delimiter="# {{" right-delimiter=}} 3 | 4 | if [ -x /home/linuxbrew/.linuxbrew/bin/brew ]; then 5 | # shellcheck disable=SC2312 6 | eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" 7 | elif [ -x "${HOME}/.linuxbrew/bin/brew" ]; then 8 | # shellcheck disable=SC2312 9 | eval "$("${HOME}/.linuxbrew/bin/brew" shellenv)" 10 | fi 11 | 12 | if [ -d "${HOME}/.volta/bin" ]; then 13 | export VOLTA_HOME="${HOME}/.volta" 14 | export PATH="${VOLTA_HOME}/bin:${PATH}" 15 | # https://docs.volta.sh/advanced/pnpm 16 | export VOLTA_FEATURE_PNPM=1 17 | fi 18 | 19 | if [ -d "${HOME}/.deno/bin" ]; then 20 | export DENO_INSTALL="${HOME}/.deno" 21 | export PATH="${DENO_INSTALL}/bin:${PATH}" 22 | fi 23 | 24 | if [ -r "${HOME}/.sdkman/bin/sdkman-init.sh" ]; then 25 | export SDKMAN_DIR="${HOME}/.sdkman" 26 | # shellcheck disable=SC1091 27 | . "${HOME}/.sdkman/bin/sdkman-init.sh" 28 | fi 29 | 30 | if [ -d "${HOME}/.local/share/flutter/bin" ]; then 31 | export PATH="${HOME}/.local/share/flutter/bin:${PATH}" 32 | fi 33 | 34 | if [ -d "${HOME}/go/bin" ]; then 35 | export PATH="${HOME}/go/bin:${PATH}" 36 | fi 37 | 38 | if [ -d "${HOME}/.cargo/bin" ]; then 39 | export PATH="${HOME}/.cargo/bin:${PATH}" 40 | fi 41 | 42 | if [ -d "${HOME}/bin" ]; then 43 | export PATH="${HOME}/bin:${PATH}" 44 | fi 45 | 46 | if [ -d "${HOME}/.local/bin" ]; then 47 | export PATH="${HOME}/.local/bin:${PATH}" 48 | fi 49 | 50 | export VISUAL="# {{ .editor }}" 51 | export EDITOR="# {{ .editor }}" 52 | 53 | # {{ if .is_wsl -}} 54 | export BROWSER="wslview" 55 | # {{- end }} 56 | -------------------------------------------------------------------------------- /home/dot_local/bin/executable_rootmoi.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ include (joinPath .chezmoi.sourceDir ".chezmoitemplates/scripts-library") }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../../.chezmoitemplates/scripts-library 7 | 8 | # {{ $configDir := joinPath .chezmoi.homeDir ".config/rootmoi" }} 9 | # {{ $configFile := joinPath $configDir "chezmoi.yaml" }} 10 | # {{ $persistentStateFile := joinPath $configDir "chezmoistate.boltdb" }} 11 | # {{ $cacheDir := joinPath .chezmoi.homeDir ".cache/rootmoi" }} 12 | 13 | # We remove chezmoi as part of the installation, so this handles it 14 | if [[ -f '{{ .chezmoi.executable }}' ]]; then 15 | executable='{{ .chezmoi.executable }}' 16 | else 17 | # chezmoi is installed with Homebrew 18 | ensure_path_entry "${HOME}/.linuxbrew/bin" "/home/linuxbrew/.linuxbrew/bin" 19 | executable=$(command -v chezmoi) 20 | fi 21 | 22 | # Ensure the folders are created, because otherwise they will be created as 23 | # root, including the ~/.cache and ~/.config, which can cause other programs 24 | # to stop working. 25 | # shellcheck disable=SC2016 26 | mkdir -p '{{ $configDir }}' '{{ $cacheDir }}' 27 | 28 | # We should not use sudo's --preserve-env option because the sudo function will 29 | # automatically bypass sudo if the user is root already. 30 | env_args=(env "PATH=${PATH}") 31 | if [[ "${DOTFILES_TEST:-}" == true ]]; then 32 | env_args+=("DOTFILES_TEST=true") 33 | fi 34 | 35 | sudo exec "${env_args[@]}" \ 36 | "${executable}" "$@" \ 37 | --config='{{ $configFile }}' \ 38 | --persistent-state='{{ $persistentStateFile }}' \ 39 | --cache='{{ $cacheDir }}' 40 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # -e: exit on error 4 | # -u: exit on unset variables 5 | set -eu 6 | 7 | log_color() { 8 | color_code="$1" 9 | shift 10 | 11 | printf "\033[${color_code}m%s\033[0m\n" "$*" >&2 12 | } 13 | 14 | log_red() { 15 | log_color "0;31" "$@" 16 | } 17 | 18 | log_blue() { 19 | log_color "0;34" "$@" 20 | } 21 | 22 | log_task() { 23 | log_blue "🔃" "$@" 24 | } 25 | 26 | log_error() { 27 | log_red "❌" "$@" 28 | } 29 | 30 | error() { 31 | log_error "$@" 32 | exit 1 33 | } 34 | 35 | if ! chezmoi="$(command -v chezmoi)"; then 36 | bin_dir="${HOME}/.local/bin" 37 | chezmoi="${bin_dir}/chezmoi" 38 | log_task "Installing chezmoi to '${chezmoi}'" 39 | if command -v curl >/dev/null; then 40 | chezmoi_install_script="$(curl -fsSL https://get.chezmoi.io)" 41 | elif command -v wget >/dev/null; then 42 | chezmoi_install_script="$(wget -qO- https://get.chezmoi.io)" 43 | else 44 | error "To install chezmoi, you must have curl or wget." 45 | fi 46 | sh -c "${chezmoi_install_script}" -- -b "${bin_dir}" 47 | unset chezmoi_install_script bin_dir 48 | fi 49 | 50 | # POSIX way to get script's dir: https://stackoverflow.com/a/29834779/12156188 51 | # shellcheck disable=SC2312 52 | script_dir="$(cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P)" 53 | 54 | set -- init --source="${script_dir}" --verbose=false "$@" 55 | 56 | if [ -n "${DOTFILES_ONE_SHOT-}" ]; then 57 | set -- "$@" --one-shot 58 | else 59 | set -- "$@" --apply 60 | fi 61 | 62 | if [ -n "${DOTFILES_DEBUG-}" ]; then 63 | set -- "$@" --debug 64 | fi 65 | 66 | log_task "Running 'chezmoi $*'" 67 | # replace current process with chezmoi 68 | exec "${chezmoi}" "$@" 69 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_20-run-rootmoi.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # chezmoi:template:left-delimiter="# {{" right-delimiter=}} 3 | 4 | # {{ template "scripts-library" }} 5 | 6 | # The following line is for ShellCheck to correctly identify the above include 7 | true || source ../.chezmoitemplates/scripts-library 8 | 9 | rootmoi_path='# {{ joinPath .chezmoi.homeDir ".local/bin/rootmoi" }}' 10 | original_args=( 11 | # {{ rest .chezmoi.args | quoteList | join " " }} 12 | ) 13 | args=(apply) 14 | 15 | # Skip if NO_ROOTMOI is set 16 | if [[ -n "${NO_ROOTMOI:-}" ]]; then 17 | exit 0 18 | fi 19 | 20 | # Filter out incompatible args 21 | skip_one_more=false 22 | for i in "${!original_args[@]}"; do 23 | if [[ "${skip_one_more}" == true ]]; then 24 | skip_one_more=false 25 | continue 26 | fi 27 | 28 | if [[ "${original_args[i]}" == "-S" || 29 | "${original_args[i]}" == "--source" ]]; then 30 | skip_one_more=true 31 | continue 32 | fi 33 | 34 | if [[ "${original_args[i]}" == "-S="* || 35 | "${original_args[i]}" == "--source="* ]]; then 36 | continue 37 | fi 38 | 39 | # We will always apply, so we don't need any --apply flags 40 | if [[ "${original_args[i]}" == "-a" || 41 | "${original_args[i]}" == "-a="* || 42 | "${original_args[i]}" == "--apply" || 43 | "${original_args[i]}" == "--apply="* ]]; then 44 | continue 45 | fi 46 | 47 | # --init never makes sense, because rootmoi's configuration is handled by 48 | # chezmoi earlier 49 | if [[ "${original_args[i]}" == "--init" ]]; then 50 | continue 51 | fi 52 | 53 | # Remove any positional args, as we will always use apply 54 | if [[ "${original_args[i]}" != "-"* ]]; then 55 | continue 56 | fi 57 | 58 | args+=("${original_args[i]}") 59 | done 60 | 61 | log_task "Applying root dotfiles" 62 | log_c "rootmoi" "${args[@]}" 63 | exec "${rootmoi_path}" "${args[@]}" 64 | -------------------------------------------------------------------------------- /home/dot_local/bin/executable_kpfd.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../../.chezmoitemplates/scripts-library 7 | 8 | trap 'jobs -pr | xargs -r kill' EXIT 9 | 10 | # https://stackoverflow.com/a/49035906/12156188 11 | # shellcheck disable=SC2312 12 | function slugify() { 13 | echo "$@" | iconv -t ascii//TRANSLIT | sed -r "s/[~\^]+//g" | sed -r "s/[^a-zA-Z0-9]+/-/g" | sed -r "s/^-+\|-+$//g" | tr "[:upper:]" "[:lower:]" 14 | } 15 | 16 | container_name="kpfd-$(slugify "$@")" 17 | 18 | kubeconfig="${KUBECONFIG:-"${HOME}/.kube/config"}" 19 | if [[ ! -f "${kubeconfig}" ]]; then 20 | error "Kubernetes configuration file not found: ${kubeconfig}" 21 | fi 22 | 23 | # Avoiding volume mount so that it works on docker on docker 24 | kubeconfig_base64="$(base64 "${kubeconfig}")" 25 | 26 | log_task "Removing any existing container named ${container_name}..." 27 | docker rm --force "${container_name}" 28 | 29 | log_task "Creating container named ${container_name}..." 30 | # shellcheck disable=SC2016 31 | docker run --name "${container_name}" \ 32 | --detach \ 33 | --restart=unless-stopped \ 34 | --pull=always \ 35 | --network=host \ 36 | --env=KUBECONFIG_BASE64="${kubeconfig_base64}" \ 37 | --entrypoint="" \ 38 | "bitnami/kubectl:${K8S_VERSION:-"latest"}" \ 39 | sh -c 'echo "${KUBECONFIG_BASE64}" | base64 -d > /.kube/config && kubectl port-forward "${@}"' -- "$@" 40 | 41 | log_task "Capturing logs from container ${container_name}..." 42 | docker logs --follow "${container_name}" & 43 | 44 | sleep 3 45 | 46 | log_green "Port-forward is now running in background." 47 | 48 | log_info "Check the logs above for possible issues." 49 | 50 | log_manual_action "You can manually stop the port-forward by running:" 51 | 52 | echo 53 | 54 | log_c docker rm --force "${container_name}" 55 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_82-configure-gnome.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | function gsettings_ensure() { 9 | local schema="$1" 10 | local key="$2" 11 | local value="$3" 12 | local extension="${4:-}" 13 | 14 | local first_args=() 15 | if [[ -n "${extension}" ]]; then 16 | first_args+=(--schemadir "${HOME}/.local/share/gnome-shell/extensions/${extension}/schemas") 17 | fi 18 | 19 | local current_value 20 | current_value="$(gsettings "${first_args[@]}" get "${schema}" "${key}")" 21 | 22 | if [[ "${current_value}" != "${value}" && "${current_value}" != "'${value}'" ]]; then 23 | log_task "Setting ${schema}.${key} to ${value}" 24 | gsettings "${first_args[@]}" set "${schema}" "${key}" "${value}" 25 | fi 26 | } 27 | 28 | # Setup VS Code as default text editor on GNOME 29 | xdg-mime default code.desktop text/plain 30 | 31 | # Configuring terminal font 32 | gsettings_ensure org.gnome.desktop.interface monospace-font-name 'FiraCode Nerd Font Mono 13' 33 | 34 | # Configuring up Yaru-dark theme 35 | gsettings_ensure org.gnome.desktop.interface gtk-theme "Yaru-dark" 36 | gsettings_ensure org.gnome.desktop.interface icon-theme "Yaru" 37 | gsettings_ensure org.gnome.desktop.interface cursor-theme "Yaru" 38 | gsettings_ensure org.gnome.desktop.sound theme-name "Yaru" 39 | # {{ if ge .chezmoi.osRelease.versionID "22.04" }} 40 | gsettings_ensure org.gnome.desktop.interface color-scheme "prefer-dark" 41 | # {{ else }} 42 | # {{ if not .is_wsl }} 43 | gsettings_ensure org.gnome.shell.extensions.user-theme name "Yaru-dark" user-theme@gnome-shell-extensions.gcampax.github.com 44 | # {{ end }} 45 | # {{ end }} 46 | 47 | # Configuring miscellaneous settings 48 | gsettings_ensure org.gtk.Settings.FileChooser show-hidden true 49 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_85-install-winget-packages-on-windows.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above include 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | win_home="$(wslvar USERPROFILE)" 9 | winget_dir="$(wslpath "${win_home}\AppData\Local\Microsoft\WindowsApps")" 10 | 11 | ensure_path_entry "${winget_dir}" 12 | 13 | function is_winget_package_installed() { 14 | local package="$1" 15 | 16 | winget.exe list --exact --id "${package}" --source winget --accept-source-agreements --disable-interactivity &>/dev/null 17 | } 18 | 19 | if ! command -v winget.exe >/dev/null; then 20 | log_task "Installing WinGet" 21 | 22 | msix_path="/tmp/winget.msixbundle" 23 | msix_path_for_win="$(wslpath -w "${msix_path}")" 24 | 25 | c curl -fsSL --output "${msix_path}" \ 26 | https://github.com/microsoft/winget-cli/releases/latest/download/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle 27 | 28 | not_during_test c PowerShell.exe -NoProfile -Command "Add-AppxPackage -Path '${msix_path_for_win}' -ForceUpdateFromAnyVersion" 29 | 30 | rm -f "${msix_path}" 31 | unset msix_path msix_path_for_win 32 | fi 33 | 34 | readonly wanted_packages=( 35 | Microsoft.VisualStudioCode 36 | Microsoft.WindowsTerminal 37 | ) 38 | 39 | missing_packages=() 40 | 41 | for package in "${wanted_packages[@]}"; do 42 | if ! is_winget_package_installed "${package}"; then 43 | missing_packages+=("${package}") 44 | fi 45 | done 46 | 47 | if [[ ${#missing_packages[@]} -gt 0 ]]; then 48 | log_task "Installing missing packages with WinGet: ${missing_packages[*]}" 49 | for package in "${missing_packages[@]}"; do 50 | not_during_test winget.exe install --exact --id "${package}" \ 51 | --source winget \ 52 | --scope user \ 53 | --accept-source-agreements \ 54 | --disable-interactivity 55 | done 56 | fi 57 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.shellcheck": "explicit" 4 | }, 5 | // Disable ShellCheck from Bash IDE as we use VS Code ShellCheck 6 | "bashIde.shellcheckPath": "", 7 | "cSpell.words": [ 8 | "C", 9 | "CODESPACES", 10 | "Cássio", 11 | "DISTRO", 12 | "Fira", 13 | "NOPASSWD", 14 | "Powerlevel", 15 | "USERPROFILE", 16 | "asciinema", 17 | "chezmoi", 18 | "chmod", 19 | "choco", 20 | "chsh", 21 | "devcontainer", 22 | "dotfiles", 23 | "felipecrs", 24 | "jfrog", 25 | "kubectl", 26 | "onedrive", 27 | "shellcheck", 28 | "ssio", 29 | "submodule", 30 | "sudoers", 31 | "wslpath", 32 | "wslvar" 33 | ], 34 | "[json]": { 35 | "editor.formatOnSave": true, 36 | "editor.defaultFormatter": "esbenp.prettier-vscode" 37 | }, 38 | "[jsonc]": { 39 | "editor.formatOnSave": true, 40 | "editor.defaultFormatter": "esbenp.prettier-vscode" 41 | }, 42 | "[shellscript]": { 43 | "editor.formatOnSave": true, 44 | "editor.defaultFormatter": "foxundermoon.shell-format" 45 | }, 46 | "shellcheck.ignorePatterns": { 47 | "**/*.zsh": true, 48 | "**/*.zshrc": true, 49 | "**/zshrc": true, 50 | "**/*.zprofile": true, 51 | "**/zprofile": true, 52 | "**/*.zlogin": true, 53 | "**/zlogin": true, 54 | "**/*.zlogout": true, 55 | "**/zlogout": true, 56 | "**/*.zshenv": true, 57 | "**/zshenv": true, 58 | "**/*.zsh-theme": true, 59 | // custom 60 | "**/*_zshrc": true 61 | }, 62 | "files.associations": { 63 | "**/home/install": "shellscript", 64 | "*_zshrc": "shellscript", 65 | "*_antigenrc": "shellscript", 66 | "*_profile.tmpl": "shellscript", 67 | "*_bashrc": "shellscript", 68 | "*_bash_aliases.tmpl": "shellscript", 69 | "**/home/**/run_*": "shellscript", 70 | "**/home/**/executable_*": "shellscript", 71 | "**/home/**/modify_*": "helm", 72 | "*.yaml.tmpl": "helm", 73 | ".chezmoi*.yaml": "helm", 74 | ".chezmoiignore": "helm", 75 | ".chezmoiremove": "helm", 76 | "**/.chezmoitemplates/*": "helm", 77 | "**/.chezmoitemplates/*-library": "shellscript" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /root/.chezmoiscripts/run_after_10-install-apt-packages.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | readonly wanted_packages=( 9 | apt-transport-https 10 | ca-certificates 11 | gnupg 12 | lsb-release 13 | dialog 14 | build-essential 15 | curl 16 | zsh 17 | wget 18 | time 19 | tree 20 | parallel 21 | file 22 | procps 23 | zip 24 | git 25 | jq 26 | python3 27 | docker-ce 28 | docker-ce-cli 29 | containerd.io 30 | docker-compose-plugin 31 | docker-buildx-plugin 32 | asciinema 33 | # provides nslookup 34 | dnsutils 35 | # {{ if .is_gnome }} 36 | yaru-theme-gtk 37 | yaru-theme-icon 38 | yaru-theme-sound 39 | gnome-tweaks 40 | gnome-menus 41 | code 42 | google-chrome-stable 43 | python3-nautilus 44 | # {{ if not .is_wsl }} 45 | yaru-theme-gnome-shell 46 | libsecret-1-0 47 | gnome-menus 48 | # {{ end }} 49 | # {{ end }} 50 | # {{ if .is_wsl }} 51 | wslu 52 | # {{ else }} 53 | # {{ if eq .chezmoi.osRelease.versionCodename "noble" }} 54 | linux-generic-hwe-24.04 55 | # {{ else if eq .chezmoi.osRelease.versionCodename "jammy" }} 56 | linux-generic-hwe-22.04 57 | # {{ else if eq .chezmoi.osRelease.versionCodename "focal" }} 58 | linux-generic-hwe-20.04 59 | # {{ end }} 60 | # {{ end }} 61 | ) 62 | missing_packages=() 63 | 64 | for package in "${wanted_packages[@]}"; do 65 | # shellcheck disable=SC2310 66 | if ! is_apt_package_installed "${package}"; then 67 | missing_packages+=("${package}") 68 | fi 69 | done 70 | 71 | if [[ ${#missing_packages[@]} -gt 0 ]]; then 72 | log_task "Installing missing packages with APT: ${missing_packages[*]}" 73 | 74 | c apt update 75 | 76 | extra_args=() 77 | if [[ "${DOTFILES_TEST:-}" == true ]]; then 78 | log_manual_action "Not installing recommended packages to speed up test mode" 79 | extra_args+=("--no-install-recommends") 80 | else 81 | extra_args+=("--install-recommends") 82 | fi 83 | 84 | c env DEBIAN_FRONTEND=noninteractive apt install --yes "${extra_args[@]}" "${missing_packages[@]}" 85 | fi 86 | -------------------------------------------------------------------------------- /home/.gitconfig.tmpl: -------------------------------------------------------------------------------- 1 | [user] 2 | name = {{ .name }} 3 | email = {{ .email }} 4 | 5 | [core] 6 | editor = {{ .editor }} 7 | excludesfile = ~/.gitignore 8 | 9 | [difftool "vscode"] 10 | cmd = code --wait --diff $LOCAL $REMOTE 11 | 12 | [mergetool "vscode"] 13 | cmd = code --wait $MERGED 14 | 15 | [diff] 16 | tool = vscode 17 | 18 | [merge] 19 | autoStash = true 20 | tool = vscode 21 | 22 | [rebase] 23 | autoStash = true 24 | 25 | [push] 26 | autoSetupRemote = true 27 | 28 | [init] 29 | defaultBranch = master 30 | 31 | [gitreview] 32 | remote = origin 33 | 34 | [include] 35 | path = ~/.config/gitalias/gitalias.txt 36 | 37 | [alias] 38 | caa = commit --amend --all 39 | caane = commit --amend --all --no-edit 40 | cob = checkout -b 41 | 42 | apply-gitignore = !f() { \ 43 | set -ex; \ 44 | git rm -r --cached . >/dev/null; \ 45 | git add .; \ 46 | };f 47 | 48 | remote-for-branch = !f() { \ 49 | set -ex; \ 50 | branch="${1:-"$(git current-branch)"}"; \ 51 | git rev-parse --abbrev-ref --symbolic-full-name "${branch}@{upstream}" | sed -n 's,^\(\S*\)/'"${branch}"'$,\1,p' | grep .; \ 52 | };f 53 | 54 | rhu = !f() { \ 55 | set -ex; \ 56 | branch="${1:-"$(git current-branch)"}"; \ 57 | remote="$(git remote-for-branch "${branch}")"; \ 58 | git reset --hard "${remote}/${branch}"; \ 59 | };f 60 | 61 | pfor = !f() { \ 62 | set -ex; \ 63 | if echo "${1}" | grep -q %; then \ 64 | branch="$(echo "${1}" | cut -d'%' -f1)"; \ 65 | push_opts="$(echo "${1}" | cut -d'%' -f2-)"; \ 66 | else \ 67 | branch="${1}"; \ 68 | push_opts=""; \ 69 | fi; \ 70 | branch="${branch:-"$(git current-branch)"}"; \ 71 | push_opts="${push_opts:+"%${push_opts}"}"; \ 72 | remote="$(git remote-for-branch "${branch}")"; \ 73 | git push "${remote}" "HEAD:refs/for/${branch}${push_opts}"; \ 74 | };f 75 | 76 | psfor = !f() { \ 77 | set -ex; \ 78 | git caane; \ 79 | git pfor "$@"; \ 80 | };f 81 | 82 | cptob = !f() { \ 83 | set -ex; \ 84 | commit="${1}"; \ 85 | shift; \ 86 | \ 87 | if echo "${1}" | grep -q ^%; then \ 88 | push_opts="${1}"; \ 89 | shift; \ 90 | else \ 91 | push_opts=""; \ 92 | fi; \ 93 | \ 94 | for branch in "${@}"; do \ 95 | git co "${branch}"; \ 96 | git rhu "${branch}"; \ 97 | git pr; \ 98 | git cp "${commit}"; \ 99 | git pfor "${branch}${push_opts}"; \ 100 | done; \ 101 | };f 102 | -------------------------------------------------------------------------------- /scripts/ensure_user_uid.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | # shellcheck disable=SC2312 6 | if [[ $(id -u) -ne 0 ]]; then 7 | echo "This script must be run as root." 8 | exit 1 9 | fi 10 | 11 | old_user="${1}" 12 | old_uid=$(id -u "${old_user}") 13 | new_uid="${2}" 14 | 15 | if [[ "${old_uid}" == "${new_uid}" ]]; then 16 | echo "User ${old_user} already has uid as ${new_uid}" 17 | exit 0 18 | fi 19 | 20 | function get_user_name() { 21 | id -nu "${1}" 22 | } 23 | 24 | function check_process_for_uid() { 25 | local user_name 26 | user_name=$(get_user_name "${1}") 27 | # shellcheck disable=SC2009 28 | if ps -ef | grep "^${user_name} "; then 29 | echo "Above is the list of processes running for user ${user_name}, please log out." 30 | return 1 31 | fi 32 | } 33 | 34 | check_process_for_uid "${old_uid}" 35 | 36 | function relocate_user() { 37 | local old=$1 38 | local name 39 | name=$(get_user_name "${old}") 40 | local new=$2 41 | 42 | # shellcheck disable=SC2312 43 | if [[ $(id -ng "${old}") != "${name}" ]]; then 44 | echo "This script only support relocating users with group that matches the uid and user name." 45 | exit 1 46 | fi 47 | 48 | # shellcheck disable=SC2312 49 | if [[ $(getent group "${name}" | wc -l) != "1" ]]; then 50 | echo "This script only support relocating users with group that have only the same user inside." 51 | exit 1 52 | fi 53 | 54 | check_process_for_uid "${old}" 55 | 56 | id "${name}" 57 | 58 | groupmod -g "${new}" "${name}" 59 | usermod -u "${new}" -g "${new}" "${name}" 60 | 61 | id "${name}" 62 | 63 | local find_args=(/ -type d '(' 64 | # https://stackoverflow.com/a/57491476/12156188 65 | -path /proc 66 | # Exclude known docker data dirs 67 | -o -path /var/lib/docker 68 | ')' -prune) 69 | 70 | find "${find_args[@]}" -o -group "${old}" -user "${old}" -print0 | xargs -0 --no-run-if-empty chown -ch "${name}:${name}" 71 | find "${find_args[@]}" -o -group "${old}" -print0 | xargs -0 --no-run-if-empty chgrp -ch "${name}" 72 | find "${find_args[@]}" -o -user "${old}" -print0 | xargs -0 --no-run-if-empty chown -ch "${name}" 73 | 74 | echo "Finished moving." 75 | } 76 | 77 | if existing_user=$(get_user_name "${new_uid}"); then 78 | next_uid=$(cat /etc/group /etc/passwd | cut -d ":" -f 3 | grep "^1...$" | sort -n | tail -n 1 | awk '{ print $1+1 }') 79 | echo "First moving existing user ${existing_user} to the next available UID/GID is ${next_uid}" 80 | 81 | relocate_user "${new_uid}" "${next_uid}" 82 | fi 83 | 84 | echo "Moving now..." 85 | relocate_user "${old_uid}" "${new_uid}" 86 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_81-install-gnome-extensions.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | 5 | # The following line is for ShellCheck to correctly identify the above included library 6 | true || source ../.chezmoitemplates/scripts-library 7 | 8 | ensure_path_entry "${HOME}/.local/bin" 9 | 10 | # TODO: install the .pyz instead after https://github.com/essembeh/gnome-extensions-cli/issues/40 11 | function gext() { 12 | uvx gnome-extensions-cli "$@" 13 | } 14 | 15 | function is_gnome_extension_installed() { 16 | local extension="$1" 17 | 18 | # https://github.com/essembeh/gnome-extensions-cli/issues/29 19 | gext list --all | sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g' | grep --quiet "(${extension})" 20 | } 21 | 22 | function is_gnome_extension_enabled() { 23 | local extension="$1" 24 | 25 | # https://github.com/essembeh/gnome-extensions-cli/issues/29 26 | gext list | sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g' | grep --quiet "(${extension})" 27 | } 28 | 29 | wanted_extensions=( 30 | dash-to-panel@jderose9.github.com 31 | arcmenu@arcmenu.com 32 | # {{ if lt .chezmoi.osRelease.versionID "22.04" }} 33 | # Ubuntu 22.04+ comes with a nice (already dark) default shell theme 34 | user-theme@gnome-shell-extensions.gcampax.github.com 35 | # {{ end }} 36 | ) 37 | 38 | unwanted_extensions=( 39 | clipboard-indicator@tudmotu.com 40 | # {{ if ge .chezmoi.osRelease.versionID "22.04" }} 41 | user-theme@gnome-shell-extensions.gcampax.github.com 42 | # {{ end }} 43 | ) 44 | 45 | disabled_extensions=( 46 | ubuntu-dock@ubuntu.com 47 | ) 48 | 49 | missing_extensions=() 50 | 51 | for extension in "${wanted_extensions[@]}"; do 52 | # shellcheck disable=SC2310 53 | if ! is_gnome_extension_installed "${extension}"; then 54 | missing_extensions+=("${extension}") 55 | fi 56 | done 57 | 58 | if [[ ${#missing_extensions[@]} -gt 0 ]]; then 59 | log_task "Installing GNOME extensions" 60 | gext install "${missing_extensions[@]}" 61 | fi 62 | 63 | for extension in "${disabled_extensions[@]}"; do 64 | if is_gnome_extension_enabled "${extension}"; then 65 | log_task "Disabling GNOME extension: ${extension}" 66 | gext disable "${extension}" 67 | fi 68 | done 69 | 70 | for extension in "${wanted_extensions[@]}"; do 71 | if ! is_gnome_extension_enabled "${extension}"; then 72 | log_task "Enabling GNOME extension: ${extension}" 73 | gext enable "${extension}" 74 | fi 75 | done 76 | 77 | for extension in "${unwanted_extensions[@]}"; do 78 | if is_gnome_extension_installed "${extension}"; then 79 | log_task "Uninstalling GNOME extension: ${extension}" 80 | gext uninstall "${extension}" 81 | fi 82 | done 83 | -------------------------------------------------------------------------------- /home/.chezmoiscripts/run_after_30-install-homebrew-packages.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | # {{ template "homebrew-library" }} 5 | 6 | # The following line is for ShellCheck to correctly identify the above include 7 | true || source ../.chezmoitemplates/scripts-library 8 | true || source ../.chezmoitemplates/homebrew-library 9 | 10 | function is_root_homebrew_prefix_writable() { 11 | if [[ -d "${root_homebrew_prefix}" ]]; then 12 | return 0 13 | elif sudo mkdir -p "${root_homebrew_prefix}" &>/dev/null; then 14 | sudo rm -rf "${root_homebrew_prefix}" 15 | return 0 16 | else 17 | return 1 18 | fi 19 | } 20 | 21 | function is_brew_package_installed() { 22 | local package="$1" 23 | 24 | brew list "${package}" &>/dev/null 25 | } 26 | 27 | if is_root_homebrew_prefix_writable && [[ -d "${home_homebrew_prefix}" ]]; then 28 | log_task "Removing old Homebrew installation" 29 | rm -rf "${home_homebrew_prefix}" 30 | fi 31 | 32 | if ! brew --version &>/dev/null; then 33 | log_task "Installing Homebrew" 34 | if is_root_homebrew_prefix_writable; then 35 | brew_install_script=$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh) 36 | CI=1 bash -c "${brew_install_script}" 37 | else 38 | homebrew_prefix="${home_homebrew_prefix}" 39 | log_info "Installing to '${homebrew_prefix}' due to lack of permissions on '/home/linuxbrew'" 40 | c git clone https://github.com/Homebrew/brew "${homebrew_prefix}/Homebrew" 41 | c mkdir -p "${homebrew_prefix}/bin" 42 | c ln -sfn "../Homebrew/bin/brew" "${homebrew_prefix}/bin" 43 | c brew update --force --quiet 44 | c chmod -R go-w "${homebrew_prefix}/share/zsh" 45 | unset homebrew_prefix 46 | fi 47 | fi 48 | 49 | readonly unwanted_packages=( 50 | jq 51 | volta 52 | deno 53 | docker-compose 54 | onedrive 55 | skopeo 56 | podman 57 | buildah 58 | asciinema 59 | kind 60 | stern 61 | ) 62 | 63 | for package in "${unwanted_packages[@]}"; do 64 | if is_brew_package_installed "${package}"; then 65 | log_task "Removing unwanted package '${package}' installed with Homebrew" 66 | brew uninstall --force "${package}" 67 | fi 68 | done 69 | 70 | readonly wanted_packages=( 71 | chezmoi 72 | yq 73 | kubectl 74 | helm 75 | k3d 76 | dive 77 | gh 78 | hadolint 79 | ) 80 | 81 | missing_packages=() 82 | 83 | for package in "${wanted_packages[@]}"; do 84 | if ! is_brew_package_installed "${package}"; then 85 | missing_packages+=("${package}") 86 | fi 87 | done 88 | 89 | if [[ ${#missing_packages[@]} -gt 0 ]]; then 90 | log_task "Installing missing packages with Homebrew: ${missing_packages[*]}" 91 | brew install --force "${missing_packages[@]}" 92 | fi 93 | -------------------------------------------------------------------------------- /scripts/install_dotfiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # -e: exit on error 4 | # -u: exit on unset variables 5 | set -eu 6 | 7 | log_color() { 8 | color_code="$1" 9 | shift 10 | 11 | printf "\033[${color_code}m%s\033[0m\n" "$*" >&2 12 | } 13 | 14 | log_red() { 15 | log_color "0;31" "$@" 16 | } 17 | 18 | log_blue() { 19 | log_color "0;34" "$@" 20 | } 21 | 22 | log_task() { 23 | log_blue "🔃" "$@" 24 | } 25 | 26 | log_manual_action() { 27 | log_red "⚠️" "$@" 28 | } 29 | 30 | log_error() { 31 | log_red "❌" "$@" 32 | } 33 | 34 | error() { 35 | log_error "$@" 36 | exit 1 37 | } 38 | 39 | sudo() { 40 | # shellcheck disable=SC2312 41 | if [ "$(id -u)" -eq 0 ]; then 42 | "$@" 43 | else 44 | if ! command sudo --non-interactive true 2>/dev/null; then 45 | log_manual_action "Root privileges are required, please enter your password below" 46 | command sudo --validate 47 | fi 48 | command sudo "$@" 49 | fi 50 | } 51 | 52 | git_clean() { 53 | path=$(realpath "$1") 54 | remote="$2" 55 | branch="$3" 56 | 57 | log_task "Cleaning '${path}' with '${remote}' at branch '${branch}'" 58 | git="git -C ${path}" 59 | # Ensure that the remote is set to the correct URL 60 | if ${git} remote | grep -q "^origin$"; then 61 | ${git} remote set-url origin "${remote}" 62 | else 63 | ${git} remote add origin "${remote}" 64 | fi 65 | ${git} checkout -B "${branch}" 66 | ${git} fetch origin "${branch}" 67 | ${git} reset --hard FETCH_HEAD 68 | ${git} clean -fdx 69 | unset path remote branch git 70 | } 71 | 72 | DOTFILES_REPO_HOST=${DOTFILES_REPO_HOST:-"https://github.com"} 73 | DOTFILES_USER=${DOTFILES_USER:-"felipecrs"} 74 | DOTFILES_REPO="${DOTFILES_REPO_HOST}/${DOTFILES_USER}/dotfiles" 75 | DOTFILES_BRANCH=${DOTFILES_BRANCH:-"master"} 76 | DOTFILES_DIR="${HOME}/.dotfiles" 77 | 78 | if ! command -v git >/dev/null 2>&1; then 79 | log_task "Installing git with APT" 80 | sudo apt update 81 | sudo env DEBIAN_FRONTEND=noninteractive apt install --yes --no-install-recommends git 82 | fi 83 | 84 | if [ -d "${DOTFILES_DIR}" ]; then 85 | git_clean "${DOTFILES_DIR}" "${DOTFILES_REPO}" "${DOTFILES_BRANCH}" 86 | else 87 | log_task "Cloning '${DOTFILES_REPO}' at branch '${DOTFILES_BRANCH}' to '${DOTFILES_DIR}'" 88 | git clone --branch "${DOTFILES_BRANCH}" "${DOTFILES_REPO}" "${DOTFILES_DIR}" 89 | fi 90 | 91 | if [ -f "${DOTFILES_DIR}/install.sh" ]; then 92 | INSTALL_SCRIPT="${DOTFILES_DIR}/install.sh" 93 | elif [ -f "${DOTFILES_DIR}/install" ]; then 94 | INSTALL_SCRIPT="${DOTFILES_DIR}/install" 95 | else 96 | error "No install script found in the dotfiles." 97 | fi 98 | 99 | log_task "Running '${INSTALL_SCRIPT}'" 100 | exec "${INSTALL_SCRIPT}" "$@" 101 | -------------------------------------------------------------------------------- /home/.chezmoitemplates/scripts-library: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | 3 | set -euo pipefail 4 | 5 | if [[ -n "${DOTFILES_DEBUG:-}" ]]; then 6 | set -x 7 | fi 8 | 9 | function ensure_path_entry() { 10 | local entries=("$@") 11 | 12 | for entry in "${entries[@]}"; do 13 | if [[ ":${PATH}:" != *":${entry}:"* ]]; then 14 | export PATH="${entry}:${PATH}" 15 | fi 16 | done 17 | } 18 | 19 | function log_color() { 20 | local color_code="$1" 21 | shift 22 | 23 | printf "\033[${color_code}m%s\033[0m\n" "$*" >&2 24 | } 25 | 26 | function log_red() { 27 | log_color "0;31" "$@" 28 | } 29 | 30 | function log_blue() { 31 | log_color "0;34" "$@" 32 | } 33 | 34 | function log_green() { 35 | log_color "1;32" "$@" 36 | } 37 | 38 | function log_yellow() { 39 | log_color "1;33" "$@" 40 | } 41 | 42 | function log_task() { 43 | log_blue "🔃" "$@" 44 | } 45 | 46 | function log_manual_action() { 47 | log_red "⚠️" "$@" 48 | } 49 | 50 | function log_c() { 51 | log_yellow "👉" "$@" 52 | } 53 | 54 | function c() { 55 | log_c "$@" 56 | "$@" 57 | } 58 | 59 | function c_exec() { 60 | log_c "$@" 61 | exec "$@" 62 | } 63 | 64 | function log_error() { 65 | log_red "❌" "$@" 66 | } 67 | 68 | function log_info() { 69 | log_blue "ℹ️" "$@" 70 | } 71 | 72 | function error() { 73 | log_error "$@" 74 | exit 1 75 | } 76 | 77 | function sudo() { 78 | local exec=false 79 | if [[ "$1" == "exec" ]]; then 80 | shift 81 | exec=true 82 | fi 83 | 84 | # shellcheck disable=SC2312 85 | if [[ "$(id -u)" -eq 0 ]]; then 86 | if [[ "${exec}" == true ]]; then 87 | exec "$@" 88 | else 89 | "$@" 90 | fi 91 | else 92 | if ! command sudo --non-interactive true 2>/dev/null; then 93 | log_manual_action "Root privileges are required, please enter your password below" 94 | command sudo --validate 95 | fi 96 | if [[ "${exec}" == true ]]; then 97 | exec sudo "$@" 98 | else 99 | command sudo "$@" 100 | fi 101 | fi 102 | } 103 | 104 | function is_apt_package_installed() { 105 | local package="$1" 106 | 107 | apt list --quiet --quiet --installed "${package}" 2>/dev/null | grep --quiet . 108 | } 109 | 110 | function not_during_test() { 111 | if [[ "${DOTFILES_TEST:-}" == true ]]; then 112 | log_info "Skipping '${*}' because we are in test mode" 113 | else 114 | "${@}" 115 | fi 116 | } 117 | 118 | # https://stackoverflow.com/a/53640320/12156188 119 | function service_exists() { 120 | local n=$1 121 | if [[ $(systemctl list-units --all -t service --full --no-legend "${n}.service" | sed 's/^\s*//g' | cut -f1 -d' ') == ${n}.service ]]; then 122 | return 0 123 | else 124 | return 1 125 | fi 126 | } 127 | -------------------------------------------------------------------------------- /root/.chezmoiexternal.yaml: -------------------------------------------------------------------------------- 1 | "usr/share/keyrings/docker.asc": 2 | type: file 3 | url: "https://download.docker.com/linux/{{ .chezmoi.osRelease.id }}/gpg" 4 | 5 | "usr/share/keyrings/git-core-ppa.asc": 6 | type: file 7 | url: "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0xF911AB184317630C59970973E363C90F8F1B6217" 8 | 9 | {{ if .is_wsl }} 10 | "usr/share/keyrings/wslu-ppa.asc": 11 | type: file 12 | url: "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x254F460F2970E18123046570C1D0E7E6AB4095D6" 13 | {{ end }} 14 | 15 | {{ if .is_gnome }} 16 | # https://github.com/microsoft/vscode/issues/255581 17 | "usr/share/keyrings/microsoft.gpg": 18 | type: file 19 | url: "https://packages.microsoft.com/keys/microsoft.asc" 20 | filter: 21 | command: gpg 22 | args: ["--dearmor"] 23 | 24 | "usr/share/keyrings/google.asc": 25 | type: file 26 | url: "https://dl.google.com/linux/linux_signing_key.pub" 27 | {{ end }} 28 | 29 | "usr/local/bin/docker-compose": 30 | type: file 31 | {{ $composeVersion := includeTemplate "get-github-latest-version" "docker/compose-switch" }} 32 | url: "https://github.com/docker/compose-switch/releases/download/v{{ $composeVersion }}/docker-compose-linux-{{ .chezmoi.arch }}" 33 | executable: true 34 | 35 | "usr/local/bin/git-lfs": 36 | type: archive-file 37 | {{ $gitLfsVersion := includeTemplate "get-github-latest-version" "git-lfs/git-lfs" }} 38 | url: "https://github.com/git-lfs/git-lfs/releases/download/v{{ $gitLfsVersion }}/git-lfs-linux-{{ .chezmoi.arch }}-v{{ $gitLfsVersion }}.tar.gz" 39 | stripComponents: 1 40 | path: git-lfs 41 | 42 | {{ $dockerCredVersion := includeTemplate "get-github-latest-version" "docker/docker-credential-helpers" }} 43 | {{ $gcmVersion := includeTemplate "get-github-latest-version" "GitCredentialManager/git-credential-manager" }} 44 | {{ if .is_wsl }} 45 | "usr/bin/docker-credential-wincred.exe": 46 | type: file 47 | url: "https://github.com/docker/docker-credential-helpers/releases/download/v{{ $dockerCredVersion }}/docker-credential-wincred-v{{ $dockerCredVersion }}.windows-{{ .chezmoi.arch }}.exe" 48 | executable: true 49 | 50 | "usr/local/share/gcm": 51 | type: archive 52 | url: "https://github.com/GitCredentialManager/git-credential-manager/releases/download/v{{ $gcmVersion }}/gcm-win-x86-{{ $gcmVersion }}.zip" 53 | exact: true 54 | {{ else }} 55 | "usr/local/share/gcm": 56 | type: archive 57 | url: "https://github.com/GitCredentialManager/git-credential-manager/releases/download/v{{ $gcmVersion }}/gcm-linux_{{ .chezmoi.arch }}.{{ $gcmVersion }}.tar.gz" 58 | exact: true 59 | 60 | {{ if .is_gnome }} 61 | "usr/bin/docker-credential-secretservice": 62 | type: file 63 | url: "https://github.com/docker/docker-credential-helpers/releases/download/v{{ $dockerCredVersion }}/docker-credential-secretservice-v{{ $dockerCredVersion }}.linux-{{ .chezmoi.arch }}" 64 | executable: true 65 | {{ end }} 66 | {{ end }} 67 | -------------------------------------------------------------------------------- /windows/powershell/Microsoft.PowerShell_profile.ps1: -------------------------------------------------------------------------------- 1 | # Oh My Posh (https://github.com/JanDeDobbeleer/oh-my-posh) 2 | # Installation: winget install JanDeDobbeleer.OhMyPosh 3 | oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH\powerlevel10k_lean.omp.json" | Invoke-Expression 4 | 5 | # PSReadLine (https://github.com/PowerShell/PSReadLine) 6 | # Installation: Install-Module PSReadLine -Force 7 | Set-PSReadLineOption -PredictionSource History 8 | Set-PSReadlineKeyHandler -Key UpArrow -Function HistorySearchBackward 9 | Set-PSReadlineKeyHandler -Key DownArrow -Function HistorySearchForward 10 | 11 | # WSL Interop (https://github.com/mikebattista/PowerShell-WSL-Interop) 12 | # Installation: Install-Module WslInterop -Force 13 | Import-WslCommand "cat", "cp", "echo", "find", "grep", "head", "ls", "mv", "rm", "sed", "touch", "tree", "which" 14 | 15 | # Chocolatey (https://github.com/chocolatey/choco) 16 | # Installation: https://chocolatey.org/install#individual 17 | if (Get-Command choco -ErrorAction SilentlyContinue) { 18 | Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" 19 | } 20 | 21 | # WinGet (https://github.com/microsoft/winget-cli) 22 | Register-ArgumentCompleter -Native -CommandName winget -ScriptBlock { 23 | param($wordToComplete, $commandAst, $cursorPosition) 24 | [Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = [System.Text.Utf8Encoding]::new() 25 | $Local:word = $wordToComplete.Replace('"', '""') 26 | $Local:ast = $commandAst.ToString().Replace('"', '""') 27 | winget complete --word="$Local:word" --commandline "$Local:ast" --position $cursorPosition | ForEach-Object { 28 | [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) 29 | } 30 | } 31 | 32 | #34de4b3d-13a8-4540-b76d-b9e8d3851756 PowerToys CommandNotFound module 33 | if (Test-Path "C:\Program Files\PowerToys\WinGetCommandNotFound.psd1") { 34 | Import-Module "C:\Program Files\PowerToys\WinGetCommandNotFound.psd1" 35 | } 36 | #34de4b3d-13a8-4540-b76d-b9e8d3851756 37 | 38 | function Refresh-Path { 39 | $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") 40 | } 41 | 42 | # gsudo (https://github.com/gerardog/gsudo) 43 | # Installation: winget install gerardog.gsudo 44 | # PSWindowsUpdate (https://github.com/mgajda83/PSWindowsUpdate) 45 | # Installation: Install-Module PSWindowsUpdate -Force 46 | function Full-Upgrade { 47 | gsudo { 48 | if (Get-Command choco -ErrorAction SilentlyContinue) { 49 | Write-Host '-> Upgrading Chocolatey packages' 50 | choco upgrade all --yes 51 | } 52 | 53 | Write-Host '-> Upgrading WinGet packages' 54 | winget upgrade --all 55 | 56 | Write-Host '-> Triggering Microsoft Store updates' 57 | # Source: https://social.technet.microsoft.com/Forums/windows/en-US/5ac7daa9-54e6-43c0-9746-293dcb8ef2ec 58 | Get-CimInstance -Namespace "Root\cimv2\mdm\dmmap" -ClassName "MDM_EnterpriseModernAppManagement_AppManagement01" | Invoke-CimMethod -MethodName UpdateScanMethod > $null 59 | 60 | Write-Host '-> Installing Windows updates' 61 | Get-WindowsUpdate -Install -AcceptAll 62 | 63 | Write-Host '-> Updating PowerShell modules' 64 | Update-Module -Confirm:$false 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /home/dot_local/bin/executable_gerrit-clone: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | red() { 4 | printf '\e[31;1m%s\e[m\n' "$*" 5 | } 6 | 7 | green() { 8 | printf '\e[32;1m%s\e[m\n' "$*" 9 | } 10 | 11 | yellow() { 12 | printf '\e[33;1m%s\e[m\n' "$*" 13 | } 14 | 15 | c() { 16 | yellow "➡ $*" 17 | "$@" 18 | } 19 | 20 | usage_error() { 21 | red "Error: $*" >&2 22 | echo >&2 23 | echo "$usage" >&2 24 | exit 2 25 | } 26 | 27 | set -euo pipefail 28 | 29 | command_name=$(basename "$0") 30 | readonly command_name 31 | 32 | readonly config_file=~/.${command_name}rc.json 33 | readonly base_url_key='defaultBaseUrl' 34 | 35 | help_text=$( 36 | cat < [] [] 60 | 61 | Example: 62 | 63 | $command_name https://review.gerrithub.io/a/felipecrs/dotfiles 64 | 65 | $command_name https://review.gerrithub.io/a/felipecrs/dotfiles ~/.dotfiles 66 | 67 | $command_name https://review.gerrithub.io/a/felipecrs/dotfiles --depth=1 68 | 69 | $command_name https://review.gerrithub.io/a/felipecrs/dotfiles ~/.dotfiles --depth=1 70 | 71 | # uses the base url defined at $config_file 72 | $command_name felipecrs/dotfiles 73 | 74 | EOM 75 | ) 76 | 77 | readonly usage 78 | 79 | if [[ -z "${1:-}" || "$1" == "--help" ]]; then 80 | echo "$help_text" 81 | echo 82 | echo "$usage" 83 | exit 0 84 | fi 85 | 86 | readonly project_regex="[-a-zA-Z0-9_./]*" 87 | # 1: protocol, 2: credentials (optional), 3: hostname, 4: auth endpoint, the "a/" (optional), 5: project name 88 | readonly url_regex="(https?)://([-a-zA-Z0-9_.:]*@)?([-a-zA-Z0-9_.:]*)/(a/)?($project_regex)" 89 | 90 | if [[ "$1" =~ ^$url_regex$ ]]; then 91 | readonly git_repository="${BASH_REMATCH[0]}" 92 | readonly protocol="${BASH_REMATCH[1]}" 93 | readonly hostname="${BASH_REMATCH[3]}" 94 | elif [[ "$1" =~ ^$project_regex$ ]]; then 95 | if [[ -f "$config_file" ]]; then 96 | if ! [[ $(command -v jq) ]]; then 97 | usage_error "jq must be installed in order to read the configuration file." 98 | fi 99 | if base_url=$(jq -er --arg b "$base_url_key" '.[$b]' "$config_file") >&2; then 100 | readonly base_url 101 | readonly git_repository="${base_url%%/}/$1" 102 | if [[ "$git_repository" =~ ^$url_regex$ ]]; then 103 | readonly protocol="${BASH_REMATCH[1]}" 104 | readonly hostname="${BASH_REMATCH[3]}" 105 | 106 | shift 107 | 108 | set -- "$git_repository" "$@" 109 | else 110 | red "Error: failed to parse url for '$git_repository'." >&2 111 | exit 1 112 | fi 113 | else 114 | usage_error "only project name is supplied but no key named '$base_url_key' is present in the configuration file." 115 | fi 116 | else 117 | usage_error "only project name is supplied but no configuration file is present at '$config_file'." 118 | fi 119 | else 120 | usage_error "the repository does not seem to be a valid http or https url, or a project name." 121 | fi 122 | 123 | # check if it's not an option 124 | if [[ -n "${2:-}" && "${2#-}" == "$2" ]]; then 125 | git_directory="$2" 126 | else 127 | git_directory="$(basename "$git_repository")" 128 | fi 129 | readonly git_directory 130 | 131 | c git clone "$@" 132 | 133 | dot_git_directory="$git_directory/$(git -C "$git_directory" rev-parse --git-dir)" 134 | readonly dot_git_directory 135 | 136 | hook="$dot_git_directory/hooks/commit-msg" 137 | readonly hook 138 | 139 | c curl -fL --create-dirs "$protocol://$hostname/tools/hooks/commit-msg" -o "$hook" 140 | 141 | c chmod +x "$hook" 142 | 143 | green "✔ Done!" 144 | -------------------------------------------------------------------------------- /home/.chezmoi.yaml.tmpl: -------------------------------------------------------------------------------- 1 | {{- $name := "Felipe Santos" -}} 2 | {{- $email := "felipecassiors@gmail.com" -}} 3 | 4 | {{- $chezmoiForce := or (has "--force" .chezmoi.args) (has "--force=true" .chezmoi.args) -}} 5 | {{- $interactive := and stdinIsATTY (not $chezmoiForce) -}} 6 | 7 | {{- $ubuntu := hasKey .chezmoi.osRelease "ubuntuCodename" -}} 8 | {{- $wsl := or (env "WSL_DISTRO_NAME") (env "IS_WSL") | not | not -}} 9 | {{- $devcontainer := or (env "REMOTE_CONTAINERS") (env "CODESPACES") (env "VSCODE_REMOTE_CONTAINERS_SESSION") (env "GITPOD_HOST") | not | not -}} 10 | {{- $gnome := lookPath "gnome-shell" | not | not -}} 11 | {{- $headless := or (env "SSH_CLIENT" | not | not) (not (or (env "DISPLAY") (env "WAYLAND_DISPLAY"))) -}} 12 | 13 | {{- $minimum := or $devcontainer (not $ubuntu) -}} 14 | 15 | {{- if hasKey . "name" -}} 16 | {{- $name = .name -}} 17 | {{- end -}} 18 | {{- if $interactive -}} 19 | {{- range $i := until 99 -}} 20 | {{- $question := "❔ What is your full name" -}} 21 | {{- $answer := "" -}} 22 | {{- if $name -}} 23 | {{- $answer = promptString $question $name -}} 24 | {{- else -}} 25 | {{- $answer = promptString $question -}} 26 | {{- end -}} 27 | {{- if regexMatch "^[A-Z][-' a-zA-Z]+$" $answer -}} 28 | {{- $name = $answer -}} 29 | {{- writeToStdout (printf "✅ Name set as '%s'\n" $name) -}} 30 | {{- break -}} 31 | {{- end -}} 32 | {{- writeToStdout (printf "❌ '%s' is an invalid name\n" $answer) -}} 33 | {{- if eq $i 98 -}} 34 | {{- writeToStdout "❌ ERROR: maximum tries exceeded\n" -}} 35 | {{- exit 1 -}} 36 | {{- end -}} 37 | {{- end -}} 38 | {{- end -}} 39 | 40 | {{- if hasKey . "email" -}} 41 | {{- $email = .email -}} 42 | {{- end -}} 43 | {{- if $interactive -}} 44 | {{- range $i := until 99 -}} 45 | {{- $question := "❔ What is your email" -}} 46 | {{- $answer := "" -}} 47 | {{- if $email -}} 48 | {{- $answer = promptString $question $email -}} 49 | {{- else -}} 50 | {{- $answer = promptString $question -}} 51 | {{- end -}} 52 | {{- $answer = lower $answer -}} 53 | {{- if regexMatch "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$" $answer -}} 54 | {{- $email = $answer -}} 55 | {{- writeToStdout (printf "✅ Email set as '%s'\n" $email) -}} 56 | {{- break -}} 57 | {{- end -}} 58 | {{- writeToStdout (printf "❌ '%s' is an invalid email\n" $answer) -}} 59 | {{- if eq $i 98 -}} 60 | {{- writeToStdout "❌ ERROR: maximum tries exceeded\n" -}} 61 | {{- exit 1 -}} 62 | {{- end -}} 63 | {{- end -}} 64 | {{- end -}} 65 | 66 | {{- if hasKey . "is_devcontainer" -}} 67 | {{- $minimum = .is_devcontainer -}} 68 | {{- end -}} 69 | {{- if $interactive -}} 70 | {{- $question := "❔ Should install in minimum mode (see README)" -}} 71 | {{- $minimum = promptBool $question $minimum -}} 72 | {{- if $minimum -}} 73 | {{- writeToStdout "✅ Minimum mode enabled\n" -}} 74 | {{- else -}} 75 | {{- writeToStdout "✅ Minimum mode disabled\n" -}} 76 | {{- end -}} 77 | {{- end -}} 78 | 79 | {{- if $interactive -}} 80 | {{- writeToStdout "\n💡 Tip: you can always make chezmoi ask this again by running `chezmoi init` without `--force`.\n" -}} 81 | {{- end -}} 82 | 83 | {{- /* This retains the value passed with --source on chezmoi init, which is used in the ../install.sh script */ -}} 84 | sourceDir: "{{ .chezmoi.workingTree }}" 85 | 86 | verbose: true 87 | 88 | # https://github.com/twpayne/chezmoi/issues/3257 89 | pager: "" 90 | 91 | diff: 92 | exclude: 93 | - scripts 94 | status: 95 | exclude: 96 | - always 97 | 98 | hooks: 99 | read-source-state: 100 | pre: 101 | command: {{ .chezmoi.workingTree }}/home/.chezmoihooks/ensure-pre-requisites.sh 102 | 103 | {{/* Here we "export" the variables, so we can access them outside this file */ -}} 104 | data: 105 | is_wsl: {{ $wsl }} 106 | is_devcontainer: {{ $minimum }} 107 | is_gnome: {{ $gnome }} 108 | is_headless: {{ $headless }} 109 | 110 | name: "{{ $name }}" 111 | email: "{{ $email }}" 112 | 113 | editor: "code --wait" 114 | 115 | uname_arch: "{{ output "uname" "-m" | trim }}" 116 | -------------------------------------------------------------------------------- /home/dot_bashrc: -------------------------------------------------------------------------------- 1 | # shellcheck shell=bash 2 | # shellcheck disable=SC2312 3 | 4 | # This file is based on Ubuntu's default .bashrc, with some customizations 5 | 6 | # ~/.bashrc: executed by bash(1) for non-login shells. 7 | # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) 8 | # for examples 9 | 10 | # if not coming from .bash_profile and .bash_profile exists 11 | if [[ -z "${COMING_FROM_BASH_PROFILE}" && -f "${HOME}/.bash_profile" ]]; then 12 | export COMING_FROM_BASHRC=true 13 | # shellcheck source=./dot_profile.tmpl 14 | source "${HOME}/.bash_profile" 15 | unset COMING_FROM_BASHRC 16 | fi 17 | 18 | # If not running interactively, don't do anything 19 | case $- in 20 | *i*) ;; 21 | *) return ;; 22 | esac 23 | 24 | # don't put duplicate lines or lines starting with space in the history. 25 | # See bash(1) for more options 26 | HISTCONTROL=ignoreboth 27 | 28 | # append to the history file, don't overwrite it 29 | shopt -s histappend 30 | 31 | # for setting history length see HISTSIZE and HISTFILESIZE in bash(1) 32 | HISTSIZE=1000 33 | HISTFILESIZE=2000 34 | 35 | # check the window size after each command and, if necessary, 36 | # update the values of LINES and COLUMNS. 37 | shopt -s checkwinsize 38 | 39 | # If set, the pattern "**" used in a pathname expansion context will 40 | # match all files and zero or more directories and subdirectories. 41 | #shopt -s globstar 42 | 43 | # make less more friendly for non-text input files, see lesspipe(1) 44 | [[ -x /usr/bin/lesspipe ]] && eval "$(SHELL=/bin/sh lesspipe)" 45 | 46 | # set variable identifying the chroot you work in (used in the prompt below) 47 | if [[ -z "${debian_chroot:-}" ]] && [[ -r /etc/debian_chroot ]]; then 48 | debian_chroot=$(cat /etc/debian_chroot) 49 | fi 50 | 51 | # set a fancy prompt (non-color, unless we know we "want" color) 52 | case "${TERM}" in 53 | xterm-color | *-256color) color_prompt=yes ;; 54 | *) ;; 55 | esac 56 | 57 | # uncomment for a colored prompt, if the terminal has the capability; turned 58 | # off by default to not distract the user: the focus in a terminal window 59 | # should be on the output of commands, not on the prompt 60 | #force_color_prompt=yes 61 | 62 | if [[ -n "${force_color_prompt}" ]]; then 63 | if [[ -x /usr/bin/tput ]] && tput setaf 1 >&/dev/null; then 64 | # We have color support; assume it's compliant with Ecma-48 65 | # (ISO/IEC-6429). (Lack of such support is extremely rare, and such 66 | # a case would tend to support setf rather than setaf.) 67 | color_prompt=yes 68 | else 69 | color_prompt= 70 | fi 71 | fi 72 | 73 | if [[ "${color_prompt}" = yes ]]; then 74 | PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' 75 | else 76 | PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' 77 | fi 78 | unset color_prompt force_color_prompt 79 | 80 | # If this is an xterm set the title to user@host:dir 81 | case "${TERM}" in 82 | xterm* | rxvt*) 83 | PS1="\[\e]0;${debian_chroot:+(${debian_chroot})}\u@\h: \w\a\]${PS1}" 84 | ;; 85 | *) ;; 86 | esac 87 | 88 | # enable color support of ls and also add handy aliases 89 | if [[ -x /usr/bin/dircolors ]]; then 90 | if [[ -r ~/.dircolors ]]; then 91 | eval "$(dircolors -b ~/.dircolors)" 92 | else 93 | eval "$(dircolors -b)" 94 | fi 95 | alias ls='ls --color=auto' 96 | #alias dir='dir --color=auto' 97 | #alias vdir='vdir --color=auto' 98 | 99 | alias grep='grep --color=auto' 100 | alias fgrep='fgrep --color=auto' 101 | alias egrep='egrep --color=auto' 102 | fi 103 | 104 | # colored GCC warnings and errors 105 | #export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01' 106 | 107 | # some more ls aliases 108 | alias ll='ls -alF' 109 | alias la='ls -A' 110 | alias l='ls -CF' 111 | 112 | # Add an "alert" alias for long running commands. Use like so: 113 | # sleep 10; alert 114 | alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' 115 | 116 | # Alias definitions. 117 | # You may want to put all your additions into a separate file like 118 | # ~/.bash_aliases, instead of adding them here directly. 119 | # See /usr/share/doc/bash-doc/examples in the bash-doc package. 120 | 121 | if [[ -f ~/.bash_aliases ]]; then 122 | # shellcheck source=./dot_bash_aliases.tmpl 123 | . ~/.bash_aliases 124 | fi 125 | 126 | # enable programmable completion features (you don't need to enable 127 | # this, if it's already enabled in /etc/bash.bashrc and /etc/profile 128 | # sources /etc/bash.bashrc). 129 | if ! shopt -oq posix; then 130 | if [[ -f /usr/share/bash-completion/bash_completion ]]; then 131 | . /usr/share/bash-completion/bash_completion 132 | elif [[ -f /etc/bash_completion ]]; then 133 | . /etc/bash_completion 134 | fi 135 | fi 136 | -------------------------------------------------------------------------------- /home/dot_local/bin/executable_full-upgrade.tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # {{ template "scripts-library" }} 4 | # {{ template "homebrew-library" }} 5 | # {{ template "volta-library" }} 6 | 7 | # The following line is for ShellCheck to correctly identify the above include 8 | true || source ../../.chezmoitemplates/scripts-library 9 | true || source ../../.chezmoitemplates/homebrew-library 10 | true || source ../../.chezmoitemplates/volta-library 11 | 12 | ensure_path_entry "${HOME}/.local/bin" 13 | 14 | if [[ "${CONTINUE_FROM_DOTFILES:-false}" == false ]]; then 15 | if brew --version &>/dev/null; then 16 | ( 17 | export HOMEBREW_NO_AUTO_UPDATE=1 18 | export HOMEBREW_NO_UPDATE_REPORT_NEW=1 19 | export HOMEBREW_NO_ENV_HINTS=1 20 | 21 | log_task "Updating brew" 22 | c brew update 23 | 24 | log_task "Updating brew packages" 25 | c brew upgrade 26 | ) 27 | fi 28 | 29 | if chezmoi --version &>/dev/null; then 30 | log_task "Updating dotfiles" 31 | 32 | if chezmoi git -- status --porcelain | grep -q .; then 33 | log_manual_action "Skipping chezmoi update as uncommitted changes were found" 34 | elif 35 | # shellcheck disable=SC2312 36 | [[ "origin/$(chezmoi git -- rev-parse --abbrev-ref HEAD)" != "$(chezmoi git -- rev-parse --abbrev-ref origin/HEAD)" ]] 37 | then 38 | log_manual_action "Skipping chezmoi update as the current branch is not the default branch" 39 | elif chezmoi git -- log '@{u}..' | grep -q .; then 40 | log_manual_action "Skipping chezmoi update as unpushed changes were found" 41 | else 42 | # Pull latest changes from dotfiles repo 43 | c chezmoi update --apply=false 44 | fi 45 | 46 | # Apply changes to chezmoi config 47 | c chezmoi init --force 48 | # Apply the rest 49 | c chezmoi apply --force 50 | fi 51 | 52 | CONTINUE_FROM_DOTFILES=true exec "$0" "$@" 53 | fi 54 | 55 | if command -v pkgs >/dev/null && pkgx --version &>/dev/null; then 56 | log_task "Updating pkgx shims" 57 | 58 | pkgx_packages="$(pkgs installed)" 59 | 60 | if [[ -z "${pkgx_packages}" ]]; then 61 | log_info "No pkgx packages found" 62 | else 63 | readarray -t pkgx_packages <<<"${pkgx_packages}" 64 | 65 | # This avoids outputting a bunch of "uninstalling" and "installing" 66 | # messages which can be confusing as we are just refreshing the stubs that 67 | # were already installed 68 | if output=$(pkgs install "${pkgx_packages[@]}" 2>&1); then 69 | unset output 70 | else 71 | # But in case of failure, we output everything to help debugging 72 | echo "${output}" >&2 73 | exit 1 74 | fi 75 | 76 | log_task "Updating pkgx packages" 77 | 78 | pkgx_packages_to_update=() 79 | for package in "${pkgx_packages[@]}"; do 80 | # This ensures we don't try to update packages that have not been cached 81 | # yet, like the ones installed but never used 82 | if [[ -d "${PKGX_DIR:-"${HOME}/.pkgx"}/${package}" ]]; then 83 | pkgx_packages_to_update+=("+${package}") 84 | fi 85 | done 86 | 87 | if [[ "${#pkgx_packages_to_update[@]}" -gt 0 ]]; then 88 | c pkgx "${pkgx_packages_to_update[@]}" >/dev/null 89 | fi 90 | 91 | unset pkgx_packages_to_update 92 | fi 93 | unset pkgx_packages 94 | fi 95 | 96 | if apt --version &>/dev/null; then 97 | log_task "Updating apt packages" 98 | c sudo apt update 99 | c sudo env DEBIAN_FRONTEND=noninteractive apt full-upgrade --yes 100 | c sudo env DEBIAN_FRONTEND=noninteractive apt autoremove --yes 101 | fi 102 | 103 | if timeout 2 snap warnings &>/dev/null; then 104 | log_task "Updating snap packages" 105 | c sudo snap refresh 106 | fi 107 | 108 | if flatpak --version &>/dev/null; then 109 | log_task "Updating flatpak packages" 110 | c sudo flatpak update --assumeyes 111 | fi 112 | 113 | if gext --version &>/dev/null; then 114 | log_task "Updating gnome extensions" 115 | c gext update --yes --user 116 | fi 117 | 118 | if pipx --version &>/dev/null; then 119 | log_task "Updating pipx packages" 120 | c pipx upgrade-all 121 | fi 122 | 123 | if volta --version &>/dev/null; then 124 | log_task "Updating node, npm, yarn, and pnpm with volta" 125 | c volta install node npm yarn pnpm 126 | fi 127 | 128 | if npm --version &>/dev/null; then 129 | log_task "Updating npm packages" 130 | c npm update --global 131 | fi 132 | 133 | if timeout 2 wsl.exe --version &>/dev/null; then 134 | log_task "Updating VS Code" 135 | # WinGet returns non zero code if no upgrade is found, so for now we simply ignore it. 136 | # Refs: https://github.com/microsoft/winget-cli/issues/3538 137 | c winget.exe upgrade --exact --id Microsoft.VisualStudioCode --source winget \ 138 | --accept-source-agreements --disable-interactivity || true 139 | 140 | log_task "Updating Windows Terminal" 141 | c winget.exe upgrade --exact --id Microsoft.WindowsTerminal --source winget \ 142 | --accept-source-agreements --disable-interactivity || true 143 | 144 | log_task "Updating WSL" 145 | log_manual_action "If an update is found, WSL will exit and you will need to open another terminal window" 146 | c wsl.exe --update 147 | fi 148 | -------------------------------------------------------------------------------- /scripts/create_alternative_chrome_shortcut.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | read -r -d '' _HELP < m4_ignore([ 18 | ### START OF CODE GENERATED BY Argbash v2.10.0 one line above ### 19 | # Argbash is a bash code generator used to get arguments parsing right. 20 | # Argbash is FREE SOFTWARE, see https://argbash.io for more info 21 | 22 | die() { 23 | local _ret="${2:-1}" 24 | test "${_PRINT_HELP:-no}" = yes && print_help >&2 25 | echo "$1" >&2 26 | exit "${_ret}" 27 | } 28 | 29 | begins_with_short_option() { 30 | local first_option all_short_options='fh' 31 | first_option="${1:0:1}" 32 | test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0 33 | } 34 | 35 | # THE DEFAULTS INITIALIZATION - POSITIONALS 36 | _positionals=() 37 | _arg_display_name="Alternative" 38 | # THE DEFAULTS INITIALIZATION - OPTIONALS 39 | _arg_force="off" 40 | 41 | print_help() { 42 | printf 'Usage: %s [-f|--(no-)force] [-h|--help] []\n' "$0" 43 | printf '\t%s\n' ": The name which will be displayed in the app launcher (default: 'Alternative')" 44 | printf '\t%s\n' "-f, --force, --no-force: Do not ask for confirmation (off by default)" 45 | printf '\t%s\n' "-h, --help: Prints help" 46 | printf '\n%s\n' "${_HELP} 47 | " 48 | } 49 | 50 | parse_commandline() { 51 | _positionals_count=0 52 | while test $# -gt 0; do 53 | _key="$1" 54 | case "${_key}" in 55 | -f | --no-force | --force) 56 | _arg_force="on" 57 | test "${1:0:5}" = "--no-" && _arg_force="off" 58 | ;; 59 | -f*) 60 | _arg_force="on" 61 | _next="${_key##-f}" 62 | if test -n "${_next}" -a "${_next}" != "${_key}"; then 63 | { begins_with_short_option "${_next}" && shift && set -- "-f" "-${_next}" "$@"; } || die "The short option '${_key}' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." 64 | fi 65 | ;; 66 | -h | --help) 67 | print_help 68 | exit 0 69 | ;; 70 | -h*) 71 | print_help 72 | exit 0 73 | ;; 74 | *) 75 | _last_positional="$1" 76 | _positionals+=("${_last_positional}") 77 | _positionals_count=$((_positionals_count + 1)) 78 | ;; 79 | esac 80 | shift 81 | done 82 | } 83 | 84 | handle_passed_args_count() { 85 | test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect between 0 and 1, but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 86 | } 87 | 88 | assign_positional_args() { 89 | local _positional_name _shift_for=$1 90 | _positional_names="_arg_display_name " 91 | 92 | shift "${_shift_for}" 93 | for _positional_name in ${_positional_names}; do 94 | test $# -gt 0 || break 95 | eval "${_positional_name}=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 96 | shift 97 | done 98 | } 99 | 100 | parse_commandline "$@" 101 | handle_passed_args_count 102 | assign_positional_args 1 "${_positionals[@]}" 103 | 104 | # OTHER STUFF GENERATED BY Argbash 105 | 106 | ### END OF CODE GENERATED BY Argbash (sortof) ### ]) 107 | # [ <-- needed because of Argbash 108 | 109 | set -euo pipefail 110 | 111 | display_name=${_arg_display_name} 112 | force=${_arg_force} 113 | 114 | default_chrome_desktop=/usr/share/applications/google-chrome.desktop 115 | if [[ ! -f "${default_chrome_desktop}" ]]; then 116 | echo "Could not find the file ${default_chrome_desktop}. Are you sure that Google Chrome is installed?" 117 | exit 1 118 | fi 119 | 120 | safe_display_name=${display_name,,} # Make lowercase 121 | safe_display_name=${safe_display_name// /-} # Replace spaces with dashes 122 | user_data_dir_name="google-chrome-${safe_display_name}" 123 | user_data_dir="${HOME}/.config/${user_data_dir_name}" 124 | shortcut="${HOME}/.local/share/applications/${user_data_dir_name}.desktop" 125 | 126 | echo 127 | echo "We will:" 128 | echo " - Create the file '${shortcut}'" 129 | echo " - Use '${display_name}' as the display name" 130 | echo " - Use '${user_data_dir}' as the user data directory" 131 | echo 132 | if [[ "${force}" = off ]]; then 133 | read -p "Do you confirm? (Yy)" -n 1 -r 134 | echo 135 | if [[ ! ${REPLY} =~ ^[Yy]$ ]]; then 136 | exit 1 137 | fi 138 | fi 139 | 140 | ## Create the shortcut 141 | cp -f "${default_chrome_desktop}" "${shortcut}" 142 | chrome_name="Google Chrome" 143 | sed -i "s:Name=${chrome_name}:Name=${chrome_name} (${display_name}):g" "${shortcut}" 144 | chrome_binary="/usr/bin/google-chrome-stable" 145 | sed -i "s:Exec=${chrome_binary}:Exec=${chrome_binary} --class=${user_data_dir_name} --user-data-dir=${user_data_dir}:g" "${shortcut}" 146 | 147 | echo 148 | echo "All done. To uninstall, run:" 149 | echo " $ rm -f ${shortcut}" 150 | echo 151 | echo "If you also want to delete the user data directory, run:" 152 | echo " $ rm -rf ${user_data_dir}" 153 | echo 154 | 155 | # ] <-- needed because of Argbash 156 | -------------------------------------------------------------------------------- /home/dot_zshrc: -------------------------------------------------------------------------------- 1 | # Load .profile 2 | if [[ -r "${HOME}/.profile" ]]; then 3 | # Do not use emulate here, as pkgx errors with unsupported shell 4 | source "${HOME}/.profile" 5 | fi 6 | 7 | # https://github.com/romkatv/powerlevel10k#how-do-i-initialize-direnv-when-using-instant-prompt 8 | if (( ${+commands[direnv]} )); then 9 | emulate zsh -c "$(direnv export zsh)" 10 | fi 11 | 12 | # Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc. 13 | # Initialization code that may require console input (password prompts, [y/n] 14 | # confirmations, etc.) must go above this block; everything else may go below. 15 | if [[ -r "${XDG_CACHE_HOME:-${HOME}/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then 16 | source "${XDG_CACHE_HOME:-${HOME}/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" 17 | fi 18 | 19 | # https://github.com/romkatv/powerlevel10k#how-do-i-initialize-direnv-when-using-instant-prompt 20 | if (( ${+commands[direnv]} )); then 21 | emulate zsh -c "$(direnv hook zsh)" 22 | fi 23 | 24 | # Load bash aliases 25 | if [[ -r "${HOME}/.bash_aliases" ]]; then 26 | # ksh is closer than sh to bash 27 | emulate ksh -c "source '${HOME}/.bash_aliases'" 28 | fi 29 | 30 | # Enable homebrew zsh completions 31 | if (( ${+commands[brew]} )); then 32 | fpath+="$(brew --prefix)/share/zsh/site-functions" 33 | fi 34 | 35 | # Oh-My-Zsh configuration 36 | 37 | # Path to your oh-my-zsh installation. 38 | export ZSH="$HOME/.oh-my-zsh" 39 | 40 | # Set name of the theme to load --- if set to "random", it will 41 | # load a random theme each time oh-my-zsh is loaded, in which case, 42 | # to know which specific one was loaded, run: echo $RANDOM_THEME 43 | # See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes 44 | ZSH_THEME="powerlevel10k/powerlevel10k" 45 | 46 | # Set list of themes to pick from when loading at random 47 | # Setting this variable when ZSH_THEME=random will cause zsh to load 48 | # a theme from this variable instead of looking in $ZSH/themes/ 49 | # If set to an empty array, this variable will have no effect. 50 | # ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) 51 | 52 | # Uncomment the following line to use case-sensitive completion. 53 | # CASE_SENSITIVE="true" 54 | 55 | # Uncomment the following line to use hyphen-insensitive completion. 56 | # Case-sensitive completion must be off. _ and - will be interchangeable. 57 | # HYPHEN_INSENSITIVE="true" 58 | 59 | # Uncomment one of the following lines to change the auto-update behavior 60 | zstyle ':omz:update' mode disabled # disable automatic updates 61 | # zstyle ':omz:update' mode auto # update automatically without asking 62 | # zstyle ':omz:update' mode reminder # just remind me to update when it's time 63 | 64 | # Uncomment the following line to change how often to auto-update (in days). 65 | # zstyle ':omz:update' frequency 13 66 | 67 | # Uncomment the following line if pasting URLs and other text is messed up. 68 | DISABLE_MAGIC_FUNCTIONS="true" 69 | 70 | # Uncomment the following line to disable colors in ls. 71 | # DISABLE_LS_COLORS="true" 72 | 73 | # Uncomment the following line to disable auto-setting terminal title. 74 | # DISABLE_AUTO_TITLE="true" 75 | 76 | # Uncomment the following line to enable command auto-correction. 77 | # ENABLE_CORRECTION="true" 78 | 79 | # Uncomment the following line to display red dots whilst waiting for completion. 80 | # You can also set it to another string to have that shown instead of the default red dots. 81 | # e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f" 82 | # Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765) 83 | # COMPLETION_WAITING_DOTS="true" 84 | 85 | # Uncomment the following line if you want to disable marking untracked files 86 | # under VCS as dirty. This makes repository status check for large repositories 87 | # much, much faster. 88 | # DISABLE_UNTRACKED_FILES_DIRTY="true" 89 | 90 | # Uncomment the following line if you want to change the command execution time 91 | # stamp shown in the history command output. 92 | # You can set one of the optional three formats: 93 | # "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" 94 | # or set a custom format using the strftime function format specifications, 95 | # see 'man strftime' for details. 96 | # HIST_STAMPS="mm/dd/yyyy" 97 | 98 | # Would you like to use another custom folder than $ZSH/custom? 99 | # ZSH_CUSTOM=/path/to/new-custom-folder 100 | 101 | # Which plugins would you like to load? 102 | # Standard plugins can be found in $ZSH/plugins/ 103 | # Custom plugins may be added to $ZSH_CUSTOM/plugins/ 104 | # Example format: plugins=(rails git textmate ruby lighthouse) 105 | # Add wisely, as too many plugins slow down shell startup. 106 | plugins=( 107 | git 108 | gh 109 | web-search 110 | docker 111 | docker-compose 112 | kubectl 113 | helm 114 | npm 115 | volta 116 | deno 117 | uv 118 | mvn 119 | ssh 120 | gitignore 121 | command-not-found 122 | common-aliases 123 | ubuntu 124 | sudo 125 | zsh-syntax-highlighting 126 | zsh-autosuggestions 127 | my-completions 128 | ) 129 | 130 | # https://github.com/zsh-users/zsh-completions/issues/603 131 | fpath+="${ZSH_CUSTOM:-"${ZSH}/custom"}/plugins/zsh-completions/src" 132 | 133 | source "${ZSH}/oh-my-zsh.sh" 134 | 135 | # Fix kubectl completion with kubecolor 136 | if command -v kubectl >/dev/null; then 137 | compdef kubecolor=kubectl 138 | fi 139 | 140 | # https://github.com/romkatv/powerlevel10k/issues/2513#issuecomment-3539890949 141 | if [[ "${TERM_PROGRAM}" == "vscode" ]]; then 142 | source "$(code --locate-shell-integration-path zsh)" 143 | fi 144 | 145 | # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh. 146 | if [[ -f "${HOME}/.p10k.zsh" ]]; then 147 | source "${HOME}/.p10k.zsh" 148 | fi 149 | -------------------------------------------------------------------------------- /home/dot_local/bin/executable_pkgs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | usage() { 6 | echo "Usage: ${0} install|uninstall|installed|installed-programs ..." >&2 7 | exit "${1}" 8 | } 9 | 10 | positional_args=() 11 | while [[ $# -gt 0 ]]; do 12 | case $1 in 13 | -*) 14 | echo "Error: unknown option ${1}." >&2 15 | usage 1 16 | ;; 17 | *) 18 | positional_args+=("$1") 19 | shift 20 | ;; 21 | esac 22 | done 23 | 24 | set -- "${positional_args[@]}" 25 | unset positional_args 26 | 27 | if [[ $# -lt 1 ]]; then 28 | usage 1 29 | fi 30 | 31 | action="$1" 32 | shift 33 | 34 | bin_dir="/usr/local/bin" 35 | uid=$(id -u) 36 | if [[ "${uid}" -ne 0 ]]; then 37 | bin_dir="${HOME}/.local/bin" 38 | fi 39 | unset uid 40 | mkdir -p "${bin_dir}" 41 | 42 | pantry_synced=false 43 | function sync_pantry_once() { 44 | if [[ "${pantry_synced}" == false ]]; then 45 | pkgx --sync --quiet 46 | pantry_synced=true 47 | fi 48 | } 49 | 50 | function resolve_pkg_spec() { 51 | local pkg="${1}" 52 | local pkg_suffix="" 53 | if [[ "${pkg}" =~ ^[^@^~]+([@^~].+)?$ ]]; then 54 | pkg_suffix="${BASH_REMATCH[1]:-}" 55 | fi 56 | sync_pantry_once 57 | pkgx --query --json=v2 "${pkg}" | jq -er '.[0].project' | sed "s/$/${pkg_suffix}/" 58 | } 59 | 60 | function is_shim() { 61 | local shim="${1}" 62 | shift 63 | local projects=("${@}") 64 | grep -I -q . "${shim}" || return 1 # binary 65 | if [[ ${#projects[@]} -gt 0 ]]; then 66 | local project 67 | local escaped_project 68 | for project in "${projects[@]}"; do 69 | # https://stackoverflow.com/a/29613573/12156188 70 | escaped_project=$(sed 's/[^^]/[&]/g; s/\^/\\^/g' <<<"${project}") 71 | head -n 1 "${shim}" | grep "^#!/usr/bin/env -S pkgx --shebang " | grep -q -E " \+${escaped_project//"."/"\."}" && return 0 72 | grep -q -E "exec pkgx \+${escaped_project//"."/"\."}" "${shim}" && return 0 # pkgx v1 73 | done 74 | else 75 | head -n 1 "${shim}" | grep -q "^#!/usr/bin/env -S pkgx --shebang " && return 0 76 | grep -q -E "exec pkgx \+[^ ]+" "${shim}" && return 0 # pkgx v1 77 | fi 78 | return 1 79 | } 80 | 81 | function get_shim_pkg_spec() { 82 | local shim="${bin_dir}/${1}" 83 | head -n 1 "${shim}" | grep "^#!/usr/bin/env -S pkgx --shebang " | grep -o -P ' \+\K[^ ]+' && return 0 84 | grep -o -m1 -P "exec pkgx \+\K[^ ]+" "${shim}" && return 0 # pkgx v1 85 | return 1 86 | } 87 | 88 | function programs_installed() { 89 | if [[ ! -d "${bin_dir}" ]]; then 90 | return 91 | fi 92 | local pkg_specs=() 93 | if [[ $# -gt 0 ]]; then 94 | local pkg 95 | for pkg in "$@"; do 96 | pkg_specs+=("$(resolve_pkg_spec "${pkg}")") 97 | done 98 | fi 99 | 100 | local bins 101 | bins="$(find "${bin_dir}" -mindepth 1 -maxdepth 1 -type f -executable)" 102 | if [[ -z "${bins}" ]]; then 103 | return 104 | fi 105 | readarray -t bins <<<"${bins}" 106 | 107 | local bin 108 | local programs=() 109 | for bin in "${bins[@]}"; do 110 | if 111 | # shellcheck disable=SC2310 112 | is_shim "${bin}" "${pkg_specs[@]}" 113 | then 114 | programs+=("$(basename "${bin}")") 115 | fi 116 | done 117 | 118 | printf '%s\n' "${programs[@]}" | sort -u 119 | } 120 | 121 | function pkgs_installed() { 122 | local programs 123 | programs=$(programs_installed "${@}") 124 | if [[ -z "${programs}" ]]; then 125 | return 126 | fi 127 | readarray -t programs <<<"${programs}" 128 | 129 | local program 130 | local pkg_specs=() 131 | for program in "${programs[@]}"; do 132 | pkg_specs+=("$(get_shim_pkg_spec "${program}")") 133 | done 134 | 135 | printf '%s\n' "${pkg_specs[@]}" | sort -u 136 | } 137 | 138 | function uninstall() { 139 | local pkg_specs=() 140 | if [[ $# -gt 0 ]]; then 141 | local pkg 142 | for pkg in "$@"; do 143 | pkg_specs+=("$(resolve_pkg_spec "${pkg}")") 144 | done 145 | fi 146 | 147 | local pkg_specs 148 | pkg_specs=$(pkgs_installed "${pkg_specs[@]}") 149 | if [[ -z "${pkg_specs}" ]]; then 150 | return 151 | fi 152 | readarray -t pkg_specs <<<"${pkg_specs}" 153 | 154 | local pkg_spec 155 | for pkg_spec in "${pkg_specs[@]}"; do 156 | local programs 157 | programs=$(programs_installed "${pkg_spec}" | grep .) 158 | if [[ -z "${programs}" ]]; then 159 | continue 160 | fi 161 | readarray -t programs <<<"${programs}" 162 | 163 | echo "uninstalling ${pkg_spec} (${programs[*]})" 164 | local program 165 | for program in "${programs[@]}"; do 166 | rm -f "${bin_dir}/${program}" 167 | done 168 | done 169 | } 170 | 171 | case "${action}" in 172 | install) 173 | if [[ $# -eq 0 ]]; then 174 | # reinstall all installed packages 175 | pkgs_text=$(pkgs_installed | grep .) 176 | readarray -t pkgs <<<"${pkgs_text}" 177 | unset pkgs_text 178 | else 179 | pkgs=("$@") 180 | fi 181 | sync_pantry_once 182 | for pkg in "${pkgs[@]}"; do 183 | if [[ "${pkg}" =~ ^[^@^~]+([@^~].+)?$ ]]; then 184 | pkg_suffix="${BASH_REMATCH[1]:-}" 185 | else 186 | pkg_suffix="" 187 | fi 188 | pkg_json=$(pkgx --query --json=v2 "${pkg}" | jq -e '.[0]') 189 | project=$(echo "${pkg_json}" | jq -er '.project') 190 | 191 | # uninstall if some version is already installed 192 | uninstall "${project}" 193 | 194 | pkg_spec="${project}${pkg_suffix}" 195 | programs_text=$(echo "${pkg_json}" | jq -er '.programs[]') 196 | readarray -t programs <<<"${programs_text}" 197 | unset programs_text 198 | 199 | for program in "${programs[@]}"; do 200 | bin="${bin_dir}/${program}" 201 | if [[ -e "${bin}" ]]; then 202 | echo "Error: ${bin} already exists and is not a pkgx shim." >&2 203 | exit 1 204 | fi 205 | done 206 | 207 | echo "installing ${pkg_spec} (${programs[*]})" 208 | for program in "${programs[@]}"; do 209 | bin="${bin_dir}/${program}" 210 | bin_tmp=$(mktemp "${bin}.tmp.XXXXXX") 211 | tee "${bin_tmp}" >/dev/null <&2 222 | fi 223 | 224 | ;; 225 | uninstall) 226 | uninstall "${@}" 227 | ;; 228 | installed-programs) 229 | programs_installed "${@}" | grep . 230 | ;; 231 | installed) 232 | pkgs_installed "${@}" | grep . 233 | ;; 234 | *) 235 | echo "Error: unknown action ${action}." >&2 236 | usage 1 237 | ;; 238 | esac 239 | -------------------------------------------------------------------------------- /scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ARG_OPTIONAL_REPEATED([variant],[v],[The variant of the test to run. Possible values: devcontainer, wsl, and gnome. Default: devcontainer.],[]) 4 | # ARG_OPTIONAL_REPEATED([os],[o],[The OS to run the tests against. The list of possible values can be found at https://mcr.microsoft.com/v2/devcontainers/base/tags/list. Examples: ubuntu-24.04, alpine. Default: ubuntu-24.04.],[]) 5 | # ARG_OPTIONAL_BOOLEAN([debug],[d],[Whether to enable debug logs or not],[off]) 6 | # ARG_OPTIONAL_SINGLE([pre-script],[],[The custom script to run before the installation],[]) 7 | # ARG_HELP([Tests the installation of the dotfiles in differents scenarios],[]) 8 | # ARGBASH_SET_INDENT([ ]) 9 | # ARGBASH_GO() 10 | # needed because of Argbash --> m4_ignore([ 11 | ### START OF CODE GENERATED BY Argbash v2.10.0 one line above ### 12 | # Argbash is a bash code generator used to get arguments parsing right. 13 | # Argbash is FREE SOFTWARE, see https://argbash.io for more info 14 | 15 | die() { 16 | local _ret="${2:-1}" 17 | test "${_PRINT_HELP:-no}" = yes && print_help >&2 18 | echo "$1" >&2 19 | exit "${_ret}" 20 | } 21 | 22 | begins_with_short_option() { 23 | local first_option all_short_options='vodh' 24 | first_option="${1:0:1}" 25 | test "${all_short_options}" = "${all_short_options/${first_option}/}" && return 1 || return 0 26 | } 27 | 28 | # THE DEFAULTS INITIALIZATION - OPTIONALS 29 | _arg_variant=() 30 | _arg_os=() 31 | _arg_debug="off" 32 | _arg_pre_script= 33 | 34 | print_help() { 35 | printf '%s\n' "Tests the installation of the dotfiles in differents scenarios" 36 | printf 'Usage: %s [-v|--variant ] [-o|--os ] [-d|--(no-)debug] [--pre-script ] [-h|--help]\n' "$0" 37 | printf '\t%s\n' "-v, --variant: The variant of the test to run. Possible values: devcontainer, wsl, and gnome. Default: devcontainer. (empty by default)" 38 | printf '\t%s\n' "-o, --os: The OS to run the tests against. The list of possible values can be found at https://mcr.microsoft.com/v2/devcontainers/base/tags/list. Examples: ubuntu-24.04, alpine. Default: ubuntu-24.04. (empty by default)" 39 | printf '\t%s\n' "-d, --debug, --no-debug: Whether to enable debug logs or not (off by default)" 40 | printf '\t%s\n' "--pre-script: The custom script to run before the installation (no default)" 41 | printf '\t%s\n' "-h, --help: Prints help" 42 | } 43 | 44 | parse_commandline() { 45 | while test $# -gt 0; do 46 | _key="$1" 47 | case "${_key}" in 48 | -v | --variant) 49 | test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 50 | _arg_variant+=("$2") 51 | shift 52 | ;; 53 | --variant=*) 54 | _arg_variant+=("${_key##--variant=}") 55 | ;; 56 | -v*) 57 | _arg_variant+=("${_key##-v}") 58 | ;; 59 | -o | --os) 60 | test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 61 | _arg_os+=("$2") 62 | shift 63 | ;; 64 | --os=*) 65 | _arg_os+=("${_key##--os=}") 66 | ;; 67 | -o*) 68 | _arg_os+=("${_key##-o}") 69 | ;; 70 | -d | --no-debug | --debug) 71 | _arg_debug="on" 72 | test "${1:0:5}" = "--no-" && _arg_debug="off" 73 | ;; 74 | -d*) 75 | _arg_debug="on" 76 | _next="${_key##-d}" 77 | if test -n "${_next}" -a "${_next}" != "${_key}"; then 78 | { begins_with_short_option "${_next}" && shift && set -- "-d" "-${_next}" "$@"; } || die "The short option '${_key}' can't be decomposed to ${_key:0:2} and -${_key:2}, because ${_key:0:2} doesn't accept value and '-${_key:2:1}' doesn't correspond to a short option." 79 | fi 80 | ;; 81 | --pre-script) 82 | test $# -lt 2 && die "Missing value for the optional argument '${_key}'." 1 83 | _arg_pre_script="$2" 84 | shift 85 | ;; 86 | --pre-script=*) 87 | _arg_pre_script="${_key##--pre-script=}" 88 | ;; 89 | -h | --help) 90 | print_help 91 | exit 0 92 | ;; 93 | -h*) 94 | print_help 95 | exit 0 96 | ;; 97 | *) 98 | _PRINT_HELP=yes die "FATAL ERROR: Got an unexpected argument '$1'" 1 99 | ;; 100 | esac 101 | shift 102 | done 103 | } 104 | 105 | parse_commandline "$@" 106 | 107 | # OTHER STUFF GENERATED BY Argbash 108 | 109 | ### END OF CODE GENERATED BY Argbash (sortof) ### ]) 110 | # [ <-- needed because of Argbash 111 | 112 | cmd() { 113 | echo "==>" "$@" 114 | "$@" 115 | } 116 | 117 | run_test() { 118 | local -r os="$1" 119 | local -r setup_script="$2" 120 | 121 | cmd time docker run --rm --init --interactive --user vscode \ 122 | --env TERM --env COLORTERM \ 123 | --volume "${dotfiles_root}:/original-dotfiles:ro" \ 124 | "mcr.microsoft.com/devcontainers/base:${os}" \ 125 | bash </dev/null 2>&1 && pwd)" 154 | dotfiles_root="$(realpath "${script_dir}/..")" 155 | 156 | debug="${_arg_debug}" 157 | variants=("${_arg_variant[@]}") 158 | if ((${#variants[@]} == 0)); then 159 | variants=("devcontainer") 160 | fi 161 | oses=("${_arg_os[@]}") 162 | if ((${#oses[@]} == 0)); then 163 | oses=("ubuntu-24.04") 164 | fi 165 | 166 | for variant in "${variants[@]}"; do 167 | for os in "${oses[@]}"; do 168 | echo "Testing variant '${variant}' with OS '${os}'" 169 | 170 | case "${variant}" in 171 | devcontainer) 172 | run_test "${os}" "export REMOTE_CONTAINERS=true" 173 | ;; 174 | 175 | wsl) 176 | run_test "${os}" "$( 177 | # shellcheck disable=SC2312 178 | cat <<'EOF' 179 | export IS_WSL=true 180 | 181 | # Exercises install-pre-requisites.sh 182 | sudo env DEBIAN_FRONTEND=noninteractive apt remove --yes --auto-remove zsh curl git 183 | 184 | cat <<'EOM' | sudo tee /usr/local/bin/wslpath 185 | #!/usr/bin/env bash 186 | 187 | echo "Hello" 188 | EOM 189 | 190 | sudo chmod +x /usr/local/bin/wslpath 191 | 192 | cat <<'EOM' | sudo tee /usr/local/bin/wslvar 193 | #!/usr/bin/env bash 194 | 195 | echo "Hello" 196 | EOM 197 | 198 | sudo chmod +x /usr/local/bin/wslvar 199 | 200 | EOF 201 | )" 202 | ;; 203 | 204 | gnome) 205 | run_test "${os}" "$( 206 | # shellcheck disable=SC2312 207 | cat <<'EOF' 208 | sudo apt update 209 | sudo env DEBIAN_FRONTEND=noninteractive apt install --yes --no-install-recommends gnome-shell 210 | EOF 211 | )" 212 | ;; 213 | 214 | *) 215 | echo "Variant '${variant}' not supported." >&2 216 | exit 1 217 | ;; 218 | esac 219 | done 220 | done 221 | 222 | # ] <-- needed because of Argbash 223 | -------------------------------------------------------------------------------- /home/.chezmoiexternal.yaml: -------------------------------------------------------------------------------- 1 | ".oh-my-zsh": 2 | type: archive 3 | {{ $omzRevision := includeTemplate "get-github-head-revision" "ohmyzsh/ohmyzsh" }} 4 | url: "https://github.com/ohmyzsh/ohmyzsh/archive/{{ $omzRevision }}.tar.gz" 5 | stripComponents: 1 6 | # waiting for https://github.com/twpayne/chezmoi/issues/1614#issuecomment-966524408 7 | # exact: true 8 | 9 | ".oh-my-zsh/custom/themes/powerlevel10k": 10 | type: archive 11 | {{ $p10kRevision := includeTemplate "get-github-head-revision" "romkatv/powerlevel10k" }} 12 | url: "https://github.com/romkatv/powerlevel10k/archive/{{ $p10kRevision }}.tar.gz" 13 | stripComponents: 1 14 | exact: true 15 | 16 | ".oh-my-zsh/custom/plugins/zsh-syntax-highlighting": 17 | type: archive 18 | {{ $zshSyntaxHighlightingRevision := includeTemplate "get-github-head-revision" "zsh-users/zsh-syntax-highlighting" }} 19 | url: "https://github.com/zsh-users/zsh-syntax-highlighting/archive/{{ $zshSyntaxHighlightingRevision }}.tar.gz" 20 | stripComponents: 1 21 | exact: true 22 | 23 | ".oh-my-zsh/custom/plugins/zsh-autosuggestions": 24 | type: archive 25 | {{ $zshAutoSuggestionsRevision := includeTemplate "get-github-head-revision" "zsh-users/zsh-autosuggestions" }} 26 | url: "https://github.com/zsh-users/zsh-autosuggestions/archive/{{ $zshAutoSuggestionsRevision }}.tar.gz" 27 | stripComponents: 1 28 | exact: true 29 | 30 | ".oh-my-zsh/custom/plugins/zsh-completions": 31 | type: archive 32 | {{ $zshCompletionsRevision := includeTemplate "get-github-head-revision" "zsh-users/zsh-completions" }} 33 | url: "https://github.com/zsh-users/zsh-completions/archive/{{ $zshCompletionsRevision }}.tar.gz" 34 | stripComponents: 1 35 | exact: true 36 | 37 | ".config/gitalias/gitalias.txt": 38 | type: file 39 | {{ $gitaliasRevision := includeTemplate "get-github-head-revision" "GitAlias/gitalias" }} 40 | url: "https://github.com/GitAlias/gitalias/raw/{{ $gitaliasRevision }}/gitalias.txt" 41 | 42 | {{ if not .is_devcontainer | or (.is_devcontainer | and (not (lookPath "retry"))) -}} 43 | ".local/bin/retry": 44 | type: file 45 | {{ $retryVersion := includeTemplate "get-github-latest-version" "kadwanev/retry" }} 46 | url: "https://github.com/kadwanev/retry/raw/{{ $retryVersion }}/retry" 47 | executable: true 48 | {{- end }} 49 | 50 | {{ if not .is_devcontainer | or (.is_devcontainer | and (not (lookPath "direnv"))) -}} 51 | ".local/bin/direnv": 52 | type: file 53 | {{ $direnvVersion := includeTemplate "get-github-latest-version" "direnv/direnv" }} 54 | url: "https://github.com/direnv/direnv/releases/download/v{{ $direnvVersion }}/direnv.linux-{{ .chezmoi.arch }}" 55 | executable: true 56 | {{- end }} 57 | 58 | {{ if not .is_devcontainer | or (.is_devcontainer | and (not (lookPath "pkgx")) | and (ne .chezmoi.osRelease.id "alpine")) -}} 59 | # Using my fork until https://github.com/pkgxdev/pkgx/pull/1187 is merged and released 60 | ".local/bin/pkgx": 61 | type: file 62 | {{ $pkgxVersion := includeTemplate "get-github-latest-version" "felipecrs/pkgx" }} 63 | url: "https://github.com/felipecrs/pkgx/releases/download/v{{ $pkgxVersion }}/pkgx-linux-{{ .chezmoi.arch }}" 64 | executable: true 65 | {{- end }} 66 | 67 | {{ if not .is_devcontainer -}} 68 | ".local/bin/uv": 69 | type: archive-file 70 | {{ $uvVersion := includeTemplate "get-github-latest-version" "astral-sh/uv" }} 71 | url: "https://github.com/astral-sh/uv/releases/download/{{ $uvVersion }}/uv-{{ .uname_arch }}-unknown-linux-gnu.tar.gz" 72 | stripComponents: 1 73 | path: uv 74 | 75 | ".local/bin/uvx": 76 | type: archive-file 77 | url: "https://github.com/astral-sh/uv/releases/download/{{ $uvVersion }}/uv-{{ .uname_arch }}-unknown-linux-gnu.tar.gz" 78 | stripComponents: 1 79 | path: uvx 80 | 81 | ".local/bin/kubecolor": 82 | type: archive-file 83 | {{ $kubecolorVersion := includeTemplate "get-github-latest-version" "kubecolor/kubecolor" }} 84 | url: "https://github.com/kubecolor/kubecolor/releases/download/v{{ $kubecolorVersion }}/kubecolor_{{ $kubecolorVersion }}_linux_{{ .chezmoi.arch }}.tar.gz" 85 | path: kubecolor 86 | 87 | ".local/bin/kubectx": 88 | type: archive-file 89 | {{ $kubectxVersion := includeTemplate "get-github-latest-version" "ahmetb/kubectx" }} 90 | url: "https://github.com/ahmetb/kubectx/releases/download/v{{ $kubectxVersion }}/kubectx_v{{ $kubectxVersion }}_linux_{{ .uname_arch }}.tar.gz" 91 | path: kubectx 92 | 93 | ".oh-my-zsh/custom/plugins/my-completions/_kubectx.zsh": 94 | type: file 95 | url: "https://github.com/ahmetb/kubectx/raw/v{{ $kubectxVersion }}/completion/_kubectx.zsh" 96 | 97 | ".local/bin/kubens": 98 | type: archive-file 99 | url: "https://github.com/ahmetb/kubectx/releases/download/v{{ $kubectxVersion }}/kubens_v{{ $kubectxVersion }}_linux_{{ .uname_arch }}.tar.gz" 100 | path: kubens 101 | 102 | ".oh-my-zsh/custom/plugins/my-completions/_kubens.zsh": 103 | type: file 104 | url: "https://github.com/ahmetb/kubectx/raw/v{{ $kubectxVersion }}/completion/_kubens.zsh" 105 | 106 | # Required by kubectx and kubens 107 | ".local/bin/fzf": 108 | type: archive-file 109 | {{ $fzfVersion := includeTemplate "get-github-latest-version" "junegunn/fzf" }} 110 | url: "https://github.com/junegunn/fzf/releases/download/v{{ $fzfVersion }}/fzf-{{ $fzfVersion }}-linux_{{ .chezmoi.arch }}.tar.gz" 111 | path: fzf 112 | 113 | ".local/bin/stern": 114 | type: archive-file 115 | {{ $sternVersion := includeTemplate "get-github-latest-version" "stern/stern" }} 116 | url: "https://github.com/stern/stern/releases/download/v{{ $sternVersion }}/stern_{{ $sternVersion }}_linux_{{ .chezmoi.arch }}.tar.gz" 117 | path: stern 118 | 119 | ".volta/bin": 120 | type: archive 121 | {{ $voltaVersion := includeTemplate "get-github-latest-version" "volta-cli/volta" }} 122 | url: "https://github.com/volta-cli/volta/releases/download/v{{ $voltaVersion }}/volta-{{ $voltaVersion }}-linux.tar.gz" 123 | 124 | {{ if .is_gnome -}} 125 | ".local/share/nautilus-python/extensions/code-nautilus.py": 126 | type: file 127 | {{ $codeNautilusRevision := includeTemplate "get-github-head-revision" "harry-cpp/code-nautilus" }} 128 | url: "https://raw.githubusercontent.com/harry-cpp/code-nautilus/{{ $codeNautilusRevision }}/code-nautilus.py" 129 | {{- end }} 130 | 131 | ".local/bin/skopeo": 132 | type: file 133 | {{ $skopeoVersion := includeTemplate "get-github-latest-version" "felipecrs/skopeo-bin" }} 134 | url: "https://github.com/felipecrs/skopeo-bin/releases/download/v{{ $skopeoVersion }}/skopeo.linux-{{ .chezmoi.arch }}" 135 | executable: true 136 | 137 | ".deno/bin/deno": 138 | type: archive-file 139 | {{ $denoVersion := includeTemplate "get-github-latest-version" "denoland/deno" }} 140 | url: "https://github.com/denoland/deno/releases/download/v{{ $denoVersion }}/deno-{{ .uname_arch }}-unknown-linux-gnu.zip" 141 | path: deno 142 | 143 | "{{ joinPath .fontsDir .terminalFont.fileName }}": 144 | type: file 145 | {{ $nerdFontsVersion := includeTemplate "get-github-latest-version" "ryanoasis/nerd-fonts" }} 146 | url: "https://raw.githubusercontent.com/ryanoasis/nerd-fonts/v{{ $nerdFontsVersion }}/patched-fonts/FiraCode/Regular/FiraCodeNerdFontMono-Regular.ttf" 147 | 148 | {{ if .is_wsl -}} 149 | {{ $externalScriptsDir := includeTemplate "get-external-scripts-dir" . }} 150 | "{{ $externalScriptsDir }}/Install-Font.ps1": 151 | type: file 152 | {{ $psWinGlueRevision := includeTemplate "get-github-head-revision" "ralish/PSWinGlue" }} 153 | url: "https://raw.githubusercontent.com/ralish/PSWinGlue/{{ $psWinGlueRevision }}/Scripts/Install-Font.ps1" 154 | 155 | "{{ $externalScriptsDir }}/Uninstall-Font.ps1": 156 | type: file 157 | url: "https://raw.githubusercontent.com/ralish/PSWinGlue/{{ $psWinGlueRevision }}/Scripts/Uninstall-Font.ps1" 158 | {{- end }} 159 | 160 | {{- end -}} 161 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Felipe Santos' dotfiles 2 | 3 | Bootstrap your Ubuntu in a single command! 4 | 5 | ![Sample dotfiles image](https://user-images.githubusercontent.com/29582865/173688885-acd1e312-4741-4ec1-bc9d-b1f31e289749.png) 6 | 7 | This dotfiles repository is currently aimed for [**Ubuntu on WSL**](https://ubuntu.com/wsl), [**Ubuntu Server**](https://ubuntu.com/server), and [**Ubuntu Desktop**](https://ubuntu.com/desktop), tested against versions **20.04**, **22.04** and **24.04**. See how to get started with WSL [here](https://docs.microsoft.com/pt-br/windows/wsl/install-win10). 8 | 9 | It's also suitable for use in [**GitHub Codespaces**](https://docs.github.com/codespaces/customizing-your-codespace/personalizing-codespaces-for-your-account#dotfiles), [**Gitpod**](https://www.gitpod.io/docs/config-dotfiles), [**VS Code Remote - Containers**](https://code.visualstudio.com/docs/remote/containers#_personalizing-with-dotfile-repositories), or even Linux distributions that are not Ubuntu, through the [**minimum mode**](#minimum-mode). 10 | 11 | Managed with [`chezmoi`](https://chezmoi.io), a great dotfiles manager. 12 | 13 | ## Getting started 14 | 15 | You can use the [convenience script](./scripts/install_dotfiles.sh) to install the dotfiles on any machine with a single command. Simply run the following command in your terminal: 16 | 17 | ```bash 18 | sh -c "$(wget -qO- https://git.io/felipecrs-dotfiles)" 19 | ``` 20 | 21 | > 💡 We use `wget` here because it comes preinstalled with most Ubuntu versions. But you can also use `curl`: 22 | > 23 | > ```bash 24 | > sh -c "$(curl -fsSL https://git.io/felipecrs-dotfiles)" 25 | > ``` 26 | 27 | ### Demo 28 | 29 | https://user-images.githubusercontent.com/29582865/173691636-63a016b2-3e9b-49a4-bb7c-5514c28a77a3.mp4 30 | 31 | ### Minimum mode 32 | 33 | The installation will ask if you want a **minimum mode installation**. The minimum mode only installs the needed dotfiles for the command prompt and is compatible with more distributions other than Ubuntu. 34 | 35 | It will be enabled by default when running in a Dev Container or in distributions other than Ubuntu. For example, I use it in order to bring my environment to the [Home Assistant VS Code Add-on](https://github.com/hassio-addons/addon-vscode). 36 | 37 | ## Configuring the terminal font 38 | 39 | This dotfiles uses the ZSH theme [Powerlevel10k](https://github.com/romkatv/powerlevel10k), so it requires you to install a font on your host machine with support for the [Nerd Fonts](https://github.com/ryanoasis/nerd-fonts) glyphs. I recommend the [`FiraCode Nerd Font Mono`](https://github.com/ryanoasis/nerd-fonts/tree/HEAD/patched-fonts/FiraCode#readme). 40 | 41 | For **WSL** and **Ubuntu Desktop**, the dotfiles installation will automatically take care of installing the font and set it up for you in **VS Code**, **Windows Terminal** (for WSL), and **GNOME Terminal** (for Ubuntu Desktop). 42 | 43 | On other systems or terminal emulators, **you will need to configure it manually**. Here are some tips: 44 | 45 | ### Installing the font on **Windows** 46 | 47 | 1. [Download it by clicking here](https://raw.githubusercontent.com/ryanoasis/nerd-fonts/HEAD/patched-fonts/FiraCode/Regular/FiraCodeNerdFontMono-Regular.ttf). 48 | 2. Open it and click in **_Install_**. 49 | 3. Restart any applications that you want to load the font into. 50 | 51 | ### Configuring the font in **VS Code** 52 | 53 | 1. On **VS Code**, press Ctrl+, to open the settings. 54 | 2. Search for "**Terminal Font Family**", and write `FiraCode Nerd Font Mono` in the entry named **_Terminal › Integrated: Font Family_**. Like below: 55 | 56 | ![VS Code font configuration example](https://user-images.githubusercontent.com/29582865/218275934-13c6579b-e470-47cf-982d-a192c9627c8e.png) 57 | 58 | ### Configuring the font in **Windows Terminal** 59 | 60 | 1. On **Windows Terminal**, press Ctrl+, to open the settings. 61 | 2. Go to **_Profiles -> Defaults_** in the left panel. Then, go to **_Additional settings -> Appearance_**. 62 | 3. At **_Text -> Font face_**, select **_FiraCode Nerd Font Mono_**. Like below: 63 | 64 | ![Windows Terminal font configuration example](https://user-images.githubusercontent.com/29582865/218276062-1b8a299c-cef3-4e80-b557-66cb5ff8a78b.png) 65 | 66 | --- 67 | 68 | ## Documentation 69 | 70 | **If you followed the steps above so far, you already finished installing the dotfiles. Have fun!** 71 | 72 | The below information is more for reference purposes. 73 | 74 | ### Convenience script 75 | 76 | The [getting started](#getting-started) step used the [convenience script](./scripts/install_dotfiles.sh) to install this dotfiles. There are some extra options that you can use to tweak the installation if you need. 77 | 78 | It supports some environment variables: 79 | 80 | - `DOTFILES_REPO_HOST`: Defaults to `https://github.com`. 81 | - `DOTFILES_USER`: Defaults to `felipecrs`. 82 | - `DOTFILES_BRANCH`: Defaults to `master`. 83 | 84 | For example, you can use it to clone and install the dotfiles repository at the `beta` branch with: 85 | 86 | ```console 87 | DOTFILES_BRANCH=beta sh -c "$(wget -qO- https://git.io/felipecrs-dotfiles)" 88 | ``` 89 | 90 | ### Installing without the convenience script 91 | 92 | If you prefer not to use the convenience script to install the dotfiles, you can also do it manually: 93 | 94 | ```bash 95 | git clone https://github.com/felipecrs/dotfiles "$HOME/.dotfiles" 96 | 97 | "$HOME/.dotfiles/install.sh" 98 | ``` 99 | 100 | --- 101 | 102 | ### Forking guide 103 | 104 | If you are forking this repository, don't forget to change the following places: 105 | 106 | - [`README.md`](./README.md) 107 | - Replace all occurrences of `https://git.io/felipecrs-dotfiles` with `https://raw.githubusercontent.com//dotfiles/HEAD/scripts/install_dotfiles.sh` 108 | - [`scripts/install_dotfiles.sh`](./scripts/install_dotfiles.sh) 109 | - Replace all occurrences of `felipecrs` with `` 110 | - [`home/.chezmoi.yaml.tmpl`](./home/.chezmoi.yaml.tmpl) 111 | - Change the name and email to yours. 112 | 113 | Where `` is your GitHub username. 114 | 115 | --- 116 | 117 | ### Extra scripts 118 | 119 | There are some scripts here to help you automate tricky activities when setting up your machine. 120 | 121 | If you already have this dotfiles [installed](#getting-started), you can use these scripts right away. Or, if you want to run it without installing the dotfiles, you can do something like: 122 | 123 | ```bash 124 | bash -c "$(curl -fsSL "https://raw.githubusercontent.com/felipecrs/dotfiles/master/scripts/")" -- 125 | ``` 126 | 127 | Just replace `` and `` with the desired values. Example: 128 | 129 | ```bash 130 | bash -c "$(curl -fsSL "https://raw.githubusercontent.com/felipecrs/dotfiles/master/scripts/create_alternative_chrome_shortcut.sh")" -- --force 131 | ``` 132 | 133 | #### [`create_alternative_chrome_shortcut.sh`](scripts/create_alternative_chrome_shortcut.sh) 134 | 135 | ##### Usage 136 | 137 | ```sh-session 138 | $ scripts/create_alternative_chrome_shortcut.sh --help 139 | Usage: scripts/create_alternative_chrome_shortcut.sh [-f|--(no-)force] [-h|--help] [] 140 | : The name which will be displayed in the app launcher (default: 'Alternative') 141 | -f, --force, --no-force: Do not ask for confirmation (off by default) 142 | -h, --help: Prints help 143 | 144 | This script creates a new shortcut for Google Chrome which opens using a 145 | different user data directory. This lets you have different icons for different 146 | instances of Google Chrome. 147 | ``` 148 | 149 | ##### Examples 150 | 151 | ```bash 152 | scripts/create_alternative_chrome_shortcut.sh Personal 153 | ``` 154 | 155 | ##### Demo 156 | 157 | ![Opening two Chrome instances using different icons](./docs/images/create_alternative_chrome_shortcut.gif) 158 | -------------------------------------------------------------------------------- /home/dot_local/bin/executable_code: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | if [ -n "${DEBUG:-}" ]; then 6 | set -x 7 | fi 8 | 9 | # This ensures there's a line between git's "hint: Waiting for your editor to close the file..." 10 | # and the next output 11 | if [ -n "${GIT_INDEX_FILE:-}" ]; then 12 | echo >&2 13 | fi 14 | 15 | # Find whether we are trying to open a directory 16 | target_dir="" 17 | for arg in "$@"; do 18 | # Skip options like --wait 19 | if [ "${arg#-}" = "${arg}" ]; then 20 | if [ -d "${arg}" ]; then 21 | target_dir="${arg}" 22 | fi 23 | break 24 | fi 25 | done 26 | unset arg 27 | 28 | # If we are trying to open a folder, drop the --wait flag to work around: 29 | # https://github.com/twpayne/chezmoi/issues/1068 30 | for arg in "$@"; do 31 | shift 32 | 33 | if [ "${arg}" = "--wait" ] || [ "${arg}" = "-w" ]; then 34 | if [ -n "${target_dir}" ]; then 35 | echo "INFO(dotfiles-code): dropping --wait since a directory is trying to be opened" >&2 36 | continue 37 | fi 38 | fi 39 | 40 | set -- "$@" "${arg}" 41 | done 42 | unset arg 43 | 44 | # Decide whether we want to try opening remote sessions or not 45 | remote=true 46 | if [ -n "${NO_REMOTE:-}" ]; then 47 | remote=false 48 | fi 49 | 50 | is_vscode_terminal=false 51 | is_vscode_terminal_native=false 52 | if [ "${TERM_PROGRAM:-}" = "vscode" ]; then 53 | is_vscode_terminal=true 54 | if [ -z "${VSCODE_IPC_HOOK_CLI:-}" ]; then 55 | is_vscode_terminal_native=true 56 | fi 57 | fi 58 | 59 | is_wsl=false 60 | if [ -n "${WSL_DISTRO_NAME:-}" ] || [ -n "${IS_WSL:-}" ]; then 61 | is_wsl=true 62 | fi 63 | 64 | # Handle --devcontainer flag 65 | devcontainer=false 66 | for arg in "$@"; do 67 | shift 68 | 69 | if [ "${arg}" = "--devcontainer" ]; then 70 | devcontainer=true 71 | 72 | if [ -n "${target_dir}" ]; then 73 | target_dir=$(realpath "${target_dir}") 74 | 75 | if ! devcontainer_workspace_folder=$( 76 | # https://github.com/microsoft/vscode-remote-release/issues/2133#issuecomment-1430651840 77 | devcontainer read-configuration --workspace-folder "${target_dir}" 2>/dev/null | 78 | jq --exit-status --raw-output .workspace.workspaceFolder 79 | ); then 80 | echo "ERROR(dotfiles-code): failed to read the devcontainer workspace folder" >&2 81 | exit 1 82 | fi 83 | 84 | if [ "${remote}" = true ] && [ "${is_wsl}" = true ]; then 85 | target_dir=$(wslpath -w "${target_dir}") 86 | fi 87 | 88 | devcontainer_path_id=$(printf "%s" "${target_dir}" | xxd -ps -c 256) 89 | break 90 | else 91 | echo "ERROR(dotfiles-code): when using --devcontainer, the first argument must be a directory" 92 | exit 1 93 | fi 94 | fi 95 | 96 | set -- "$@" "${arg}" 97 | done 98 | unset arg 99 | 100 | exec_code() { 101 | code="$1" 102 | shift 103 | 104 | if [ "${devcontainer}" = false ]; then 105 | exec "${code}" "$@" 106 | fi 107 | 108 | devcontainer_remote_id="" 109 | if [ -n "${ssh_host:-}" ]; then 110 | devcontainer_remote_id="@ssh-remote%2B${ssh_host}" 111 | elif [ "${is_wsl}" = false ] && [ -n "${VSCODE_IPC_HOOK_CLI:-}" ]; then 112 | # Try to find remote tunnel host 113 | if tunnel_host=$( 114 | "${code}" --status 2>/dev/null | grep -oP "^Remote:[ ]+\K.+" | grep -v '[ :]' | head -1 | grep . 115 | ); then 116 | devcontainer_remote_id="@tunnel%2B${tunnel_host}" 117 | else 118 | echo "ERROR(dotfiles-code): failed to get the remote id" >&2 119 | exit 1 120 | fi 121 | fi 122 | exec "${code}" --folder-uri "vscode-remote://dev-container%2B${devcontainer_path_id}${devcontainer_remote_id}${devcontainer_workspace_folder}" 123 | } 124 | 125 | # When called from within VS Code Insiders terminal, prefer using code-insiders 126 | if [ "${is_vscode_terminal}" = true ] && echo "${TERM_PROGRAM_VERSION:-}" | grep -q -- "-insider$"; then 127 | # shellcheck disable=SC2230 128 | executables=$(which -a code-insiders) 129 | else 130 | # Only consider next "code"s in PATH 131 | this_script=$(realpath "$0") 132 | executables=$( 133 | # shellcheck disable=SC2230 134 | which -a code | grep -A99 "${this_script}" | grep -v "${this_script}" || true 135 | ) 136 | unset this_script 137 | fi 138 | 139 | vscode_server_dir="${HOME}/.vscode-server" 140 | 141 | if [ "${remote}" = false ]; then 142 | echo "INFO(dotfiles-code): using code from linux" >&2 143 | # Avoids reopening the remote session if called from within the remote session 144 | unset VSCODE_IPC_HOOK_CLI 145 | if [ "${is_wsl}" = true ]; then 146 | export DONT_PROMPT_WSL_INSTALL=1 147 | executables=$(echo "${executables}" | grep -v '^/mnt/.*$' || true) 148 | fi 149 | executables=$(echo "${executables}" | grep -v "${vscode_server_dir}" || true) 150 | elif [ "${is_wsl}" = true ]; then 151 | if [ "${is_vscode_terminal_native}" = true ]; then 152 | # Already inside native VS Code terminal, no need to warn again 153 | export DONT_PROMPT_WSL_INSTALL=1 154 | elif [ "${is_vscode_terminal}" = false ]; then 155 | echo "INFO(dotfiles-code): using code from windows (set NO_REMOTE=1 to disable this)" >&2 156 | executables=$(echo "${executables}" | grep '^/mnt/.*$' || true) 157 | fi 158 | elif [ "${is_vscode_terminal}" = false ] && who -m | grep -q .; then 159 | # We will try to find an existing SSH connection and reuse it. This allows 160 | # opening VS Code windows from a SSH remote session even out of the VS Code 161 | # integrated terminal. 162 | # PS: this only works if there is at least one VS Code window already 163 | # connected to this machine. 164 | echo "INFO(dotfiles-code): ssh session detected, searching for vscode remote sessions (set NO_REMOTE=1 to disable this)" >&2 165 | no_sockets_message="no vscode remote sessions found" 166 | code_search_dir="${vscode_server_dir}/cli/servers" 167 | if [ -d "${code_search_dir}" ]; then 168 | # Find the most recent directory inside of code_search_dir 169 | if code_search_dir=$( 170 | find "${code_search_dir}" \ 171 | -mindepth 1 -maxdepth 1 -type d -printf "%T@ %p\n" | 172 | sort -nr | cut -d' ' -f 2- | head -1 | grep . 173 | ); then 174 | # Ensure the bin is valid 175 | code="${code_search_dir}/server/bin/remote-cli/code" 176 | if [ -x "${code}" ]; then 177 | # Find all vscode-ipc-*.sock files, trying to connect to the newest first 178 | uid=$(id -u) 179 | if sockets=$( 180 | find "/run/user/${uid}/" \ 181 | -mindepth 1 -maxdepth 1 -type s -name "vscode-ipc-*.sock" -printf "%T@ %p\n" | 182 | sort -nr | cut -d' ' -f 2- | grep . 183 | ); then 184 | sockets_count=$(echo "${sockets}" | wc -l) 185 | echo "INFO(dotfiles-code): ${sockets_count} vscode remote sessions found" >&2 186 | unset sockets_count 187 | 188 | for socket in ${sockets}; do 189 | echo "INFO(dotfiles-code): trying to connect to ${socket}" >&2 190 | export VSCODE_IPC_HOOK_CLI="${socket}" 191 | if ssh_host=$( 192 | timeout 5s "${code}" --status 2>/dev/null | grep -m1 -oP "^Remote:[ ]+SSH:[ ]+\K.+" 193 | ); then 194 | echo "INFO(dotfiles-code): worked, using it" >&2 195 | exec_code "${code}" "$@" 196 | else 197 | echo "INFO(dotfiles-code): did not work" >&2 198 | fi 199 | done 200 | 201 | no_sockets_message="no more vscode remote sessions found" 202 | unset socket VSCODE_IPC_HOOK_CLI output 203 | fi 204 | unset uid sockets 205 | fi 206 | unset code 207 | fi 208 | fi 209 | echo "WARNING(dotfiles-code): ${no_sockets_message}" >&2 210 | unset code_search_dir no_sockets_message 211 | fi 212 | 213 | if code=$(echo "${executables}" | head -1 | grep .); then 214 | exec_code "${code}" "$@" 215 | fi 216 | 217 | # When NO_REMOTE is set, we should not try to fallback because the user has 218 | # explicitly requested an intention to use code. 219 | if [ "${remote}" = false ]; then 220 | echo "ERROR(dotfiles-code): code is not available" >&2 221 | exit 127 222 | fi 223 | 224 | echo "WARNING(dotfiles-code): code is not available" >&2 225 | if command -v code-insiders >/dev/null; then 226 | echo "INFO(dotfiles-code): using code-insiders instead" >&2 227 | exec_code code-insiders "$@" 228 | fi 229 | 230 | if [ -n "${target_dir}" ]; then 231 | echo "ERROR(dotfiles-code): not falling back to nano, vim, or vi since a directory is trying to be opened" >&2 232 | exit 127 233 | fi 234 | 235 | if command -v nano >/dev/null; then 236 | editor="nano" 237 | elif command -v vim >/dev/null; then 238 | editor="vim" 239 | elif command -v vi >/dev/null; then 240 | editor="vi" 241 | else 242 | echo "ERROR(dotfiles-code): neither code-insiders, nano, vim, or vi is available" >&2 243 | exit 127 244 | fi 245 | 246 | echo "INFO(dotfiles-code): using ${editor} instead" >&2 247 | 248 | for arg in "$@"; do 249 | shift 250 | 251 | # Remove the --wait flag as it's not supported by nano, vim, or vi 252 | if [ "${arg}" = "--wait" ] || [ "${arg}" = "-w" ]; then 253 | echo "INFO(dotfiles-code): dropping --wait as it's not supported by ${editor}" >&2 254 | continue 255 | fi 256 | 257 | # If any other option is passed, we fail 258 | if [ "${arg#-}" != "${arg}" ]; then 259 | echo "ERROR(dotfiles-code): not falling back to ${editor} since ${arg} was passed" >&2 260 | exit 127 261 | fi 262 | 263 | set -- "$@" "${arg}" 264 | done 265 | 266 | exec "${editor}" "$@" 267 | -------------------------------------------------------------------------------- /windows/terminal/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$help": "https://aka.ms/terminal-documentation", 3 | "$schema": "https://aka.ms/terminal-profiles-schema", 4 | "copyFormatting": "none", 5 | "copyOnSelect": false, 6 | "keybindings": [ 7 | { 8 | "id": "Terminal.CopyToClipboard", 9 | "keys": "ctrl+c" 10 | }, 11 | { 12 | "id": "Terminal.PasteFromClipboard", 13 | "keys": "ctrl+v" 14 | }, 15 | { 16 | "id": "Terminal.FindText", 17 | "keys": "ctrl+f" 18 | }, 19 | { 20 | "id": "Terminal.DuplicatePaneAuto", 21 | "keys": "alt+shift+d" 22 | } 23 | ], 24 | "defaultProfile": "{f35fc667-d3e6-567f-b82b-408e44d3e7f0}", 25 | "launchMode": "maximized", 26 | "newTabMenu": [ 27 | { 28 | "type": "remainingProfiles" 29 | } 30 | ], 31 | "profiles": { 32 | "defaults": { 33 | "backgroundImage": "desktopWallpaper", 34 | "backgroundImageOpacity": 0.1, 35 | "colorScheme": "Material Palenight High Contrast", 36 | "font": { 37 | "face": "FiraCode Nerd Font Mono", 38 | "size": 16.0 39 | } 40 | }, 41 | "list": [ 42 | { 43 | "guid": "{f35fc667-d3e6-567f-b82b-408e44d3e7f0}", 44 | "hidden": false, 45 | "name": "Ubuntu", 46 | "source": "Microsoft.WSL", 47 | "closeOnExit": "graceful", 48 | }, 49 | { 50 | "guid": "{574e775e-4f2a-5b96-ac1e-a2962a402336}", 51 | "hidden": false, 52 | "name": "PowerShell", 53 | "source": "Windows.Terminal.PowershellCore" 54 | }, 55 | { 56 | "guid": "{2ece5bfe-50ed-5f3a-ab87-5cd4baafed2b}", 57 | "hidden": false, 58 | "name": "Git Bash", 59 | "source": "Git" 60 | }, 61 | { 62 | "commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", 63 | "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}", 64 | "hidden": false, 65 | "name": "Windows PowerShell" 66 | }, 67 | { 68 | "commandline": "%SystemRoot%\\System32\\cmd.exe", 69 | "guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}", 70 | "hidden": false, 71 | "name": "Command Prompt" 72 | }, 73 | { 74 | "guid": "{b453ae62-4e3d-5e58-b989-0a998ec441b8}", 75 | "hidden": true, 76 | "name": "Azure Cloud Shell", 77 | "source": "Windows.Terminal.Azure" 78 | }, 79 | { 80 | "guid": "{51855cb2-8cce-5362-8f54-464b92b32386}", 81 | "hidden": true, 82 | "name": "Ubuntu", 83 | "source": "CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc" 84 | } 85 | ] 86 | }, 87 | "schemes": [ 88 | { 89 | "background": "#0C0C0C", 90 | "black": "#0C0C0C", 91 | "blue": "#0037DA", 92 | "brightBlack": "#767676", 93 | "brightBlue": "#3B78FF", 94 | "brightCyan": "#61D6D6", 95 | "brightGreen": "#16C60C", 96 | "brightPurple": "#B4009E", 97 | "brightRed": "#E74856", 98 | "brightWhite": "#F2F2F2", 99 | "brightYellow": "#F9F1A5", 100 | "cursorColor": "#FFFFFF", 101 | "cyan": "#3A96DD", 102 | "foreground": "#CCCCCC", 103 | "green": "#13A10E", 104 | "name": "Campbell", 105 | "purple": "#881798", 106 | "red": "#C50F1F", 107 | "selectionBackground": "#FFFFFF", 108 | "white": "#CCCCCC", 109 | "yellow": "#C19C00" 110 | }, 111 | { 112 | "background": "#012456", 113 | "black": "#0C0C0C", 114 | "blue": "#0037DA", 115 | "brightBlack": "#767676", 116 | "brightBlue": "#3B78FF", 117 | "brightCyan": "#61D6D6", 118 | "brightGreen": "#16C60C", 119 | "brightPurple": "#B4009E", 120 | "brightRed": "#E74856", 121 | "brightWhite": "#F2F2F2", 122 | "brightYellow": "#F9F1A5", 123 | "cursorColor": "#FFFFFF", 124 | "cyan": "#3A96DD", 125 | "foreground": "#CCCCCC", 126 | "green": "#13A10E", 127 | "name": "Campbell Powershell", 128 | "purple": "#881798", 129 | "red": "#C50F1F", 130 | "selectionBackground": "#FFFFFF", 131 | "white": "#CCCCCC", 132 | "yellow": "#C19C00" 133 | }, 134 | { 135 | "background": "#1B1E2B", 136 | "black": "#000000", 137 | "blue": "#82AAFF", 138 | "brightBlack": "#676E95", 139 | "brightBlue": "#82AAFF", 140 | "brightCyan": "#89DDFF", 141 | "brightGreen": "#C3E88D", 142 | "brightPurple": "#C792EA", 143 | "brightRed": "#F07178", 144 | "brightWhite": "#FFFFFF", 145 | "brightYellow": "#FFCB6B", 146 | "cursorColor": "#FFFFFF", 147 | "cyan": "#89DDFF", 148 | "foreground": "#A6ACCD", 149 | "green": "#C3E88D", 150 | "name": "Material Palenight High Contrast", 151 | "purple": "#C792EA", 152 | "red": "#F07178", 153 | "selectionBackground": "#FFFFFF", 154 | "white": "#FFFFFF", 155 | "yellow": "#FFCB6B" 156 | }, 157 | { 158 | "background": "#282C34", 159 | "black": "#282C34", 160 | "blue": "#61AFEF", 161 | "brightBlack": "#5A6374", 162 | "brightBlue": "#61AFEF", 163 | "brightCyan": "#56B6C2", 164 | "brightGreen": "#98C379", 165 | "brightPurple": "#C678DD", 166 | "brightRed": "#E06C75", 167 | "brightWhite": "#DCDFE4", 168 | "brightYellow": "#E5C07B", 169 | "cursorColor": "#FFFFFF", 170 | "cyan": "#56B6C2", 171 | "foreground": "#DCDFE4", 172 | "green": "#98C379", 173 | "name": "One Half Dark", 174 | "purple": "#C678DD", 175 | "red": "#E06C75", 176 | "selectionBackground": "#FFFFFF", 177 | "white": "#DCDFE4", 178 | "yellow": "#E5C07B" 179 | }, 180 | { 181 | "background": "#FAFAFA", 182 | "black": "#383A42", 183 | "blue": "#0184BC", 184 | "brightBlack": "#4F525D", 185 | "brightBlue": "#61AFEF", 186 | "brightCyan": "#56B5C1", 187 | "brightGreen": "#98C379", 188 | "brightPurple": "#C577DD", 189 | "brightRed": "#DF6C75", 190 | "brightWhite": "#FFFFFF", 191 | "brightYellow": "#E4C07A", 192 | "cursorColor": "#4F525D", 193 | "cyan": "#0997B3", 194 | "foreground": "#383A42", 195 | "green": "#50A14F", 196 | "name": "One Half Light", 197 | "purple": "#A626A4", 198 | "red": "#E45649", 199 | "selectionBackground": "#4F525D", 200 | "white": "#FAFAFA", 201 | "yellow": "#C18301" 202 | }, 203 | { 204 | "background": "#002B36", 205 | "black": "#002B36", 206 | "blue": "#268BD2", 207 | "brightBlack": "#073642", 208 | "brightBlue": "#839496", 209 | "brightCyan": "#93A1A1", 210 | "brightGreen": "#586E75", 211 | "brightPurple": "#6C71C4", 212 | "brightRed": "#CB4B16", 213 | "brightWhite": "#FDF6E3", 214 | "brightYellow": "#657B83", 215 | "cursorColor": "#FFFFFF", 216 | "cyan": "#2AA198", 217 | "foreground": "#839496", 218 | "green": "#859900", 219 | "name": "Solarized Dark", 220 | "purple": "#D33682", 221 | "red": "#DC322F", 222 | "selectionBackground": "#FFFFFF", 223 | "white": "#EEE8D5", 224 | "yellow": "#B58900" 225 | }, 226 | { 227 | "background": "#FDF6E3", 228 | "black": "#002B36", 229 | "blue": "#268BD2", 230 | "brightBlack": "#073642", 231 | "brightBlue": "#839496", 232 | "brightCyan": "#93A1A1", 233 | "brightGreen": "#586E75", 234 | "brightPurple": "#6C71C4", 235 | "brightRed": "#CB4B16", 236 | "brightWhite": "#FDF6E3", 237 | "brightYellow": "#657B83", 238 | "cursorColor": "#002B36", 239 | "cyan": "#2AA198", 240 | "foreground": "#657B83", 241 | "green": "#859900", 242 | "name": "Solarized Light", 243 | "purple": "#D33682", 244 | "red": "#DC322F", 245 | "selectionBackground": "#073642", 246 | "white": "#EEE8D5", 247 | "yellow": "#B58900" 248 | }, 249 | { 250 | "background": "#000000", 251 | "black": "#000000", 252 | "blue": "#3465A4", 253 | "brightBlack": "#555753", 254 | "brightBlue": "#729FCF", 255 | "brightCyan": "#34E2E2", 256 | "brightGreen": "#8AE234", 257 | "brightPurple": "#AD7FA8", 258 | "brightRed": "#EF2929", 259 | "brightWhite": "#EEEEEC", 260 | "brightYellow": "#FCE94F", 261 | "cursorColor": "#FFFFFF", 262 | "cyan": "#06989A", 263 | "foreground": "#D3D7CF", 264 | "green": "#4E9A06", 265 | "name": "Tango Dark", 266 | "purple": "#75507B", 267 | "red": "#CC0000", 268 | "selectionBackground": "#FFFFFF", 269 | "white": "#D3D7CF", 270 | "yellow": "#C4A000" 271 | }, 272 | { 273 | "background": "#FFFFFF", 274 | "black": "#000000", 275 | "blue": "#3465A4", 276 | "brightBlack": "#555753", 277 | "brightBlue": "#729FCF", 278 | "brightCyan": "#34E2E2", 279 | "brightGreen": "#8AE234", 280 | "brightPurple": "#AD7FA8", 281 | "brightRed": "#EF2929", 282 | "brightWhite": "#EEEEEC", 283 | "brightYellow": "#FCE94F", 284 | "cursorColor": "#000000", 285 | "cyan": "#06989A", 286 | "foreground": "#555753", 287 | "green": "#4E9A06", 288 | "name": "Tango Light", 289 | "purple": "#75507B", 290 | "red": "#CC0000", 291 | "selectionBackground": "#555753", 292 | "white": "#D3D7CF", 293 | "yellow": "#C4A000" 294 | }, 295 | { 296 | "background": "#300A24", 297 | "black": "#171421", 298 | "blue": "#0037DA", 299 | "brightBlack": "#767676", 300 | "brightBlue": "#08458F", 301 | "brightCyan": "#2C9FB3", 302 | "brightGreen": "#26A269", 303 | "brightPurple": "#A347BA", 304 | "brightRed": "#C01C28", 305 | "brightWhite": "#F2F2F2", 306 | "brightYellow": "#A2734C", 307 | "cursorColor": "#FFFFFF", 308 | "cyan": "#3A96DD", 309 | "foreground": "#FFFFFF", 310 | "green": "#26A269", 311 | "name": "Ubuntu-ColorScheme", 312 | "purple": "#881798", 313 | "red": "#C21A23", 314 | "selectionBackground": "#FFFFFF", 315 | "white": "#CCCCCC", 316 | "yellow": "#A2734C" 317 | }, 318 | { 319 | "background": "#000000", 320 | "black": "#000000", 321 | "blue": "#000080", 322 | "brightBlack": "#808080", 323 | "brightBlue": "#0000FF", 324 | "brightCyan": "#00FFFF", 325 | "brightGreen": "#00FF00", 326 | "brightPurple": "#FF00FF", 327 | "brightRed": "#FF0000", 328 | "brightWhite": "#FFFFFF", 329 | "brightYellow": "#FFFF00", 330 | "cursorColor": "#FFFFFF", 331 | "cyan": "#008080", 332 | "foreground": "#C0C0C0", 333 | "green": "#008000", 334 | "name": "Vintage", 335 | "purple": "#800080", 336 | "red": "#800000", 337 | "selectionBackground": "#FFFFFF", 338 | "white": "#C0C0C0", 339 | "yellow": "#808000" 340 | } 341 | ], 342 | "theme": "system", 343 | "themes": [], 344 | "windowingBehavior": "useExisting" 345 | } 346 | --------------------------------------------------------------------------------