6 Commits

Author SHA1 Message Date
3b312e6f9a Fix 1password role on Windows
When 1password is already installed and the installer is invoked, it
hangs because it launches the GUI and never returns.
2023-07-29 11:53:22 +01:00
e625f463d7 Add Windows support to fonts role 2023-07-29 11:33:20 +01:00
47d9c4c7e7 Remove broken win_git: module 2023-07-29 10:37:50 +01:00
0f78fe6a69 Fix obsidian desktop file icon 2023-07-27 23:39:57 +01:00
c78ea00ae4 Add ferdium role, prep for removing webcatalog
In the trend of 2023 enshitification webcatalog has decided to stop
shipping a Linux version so I'll be moving to fetdium with a self-hosted
server moving forwards.
2023-07-27 23:38:09 +01:00
bec20420ff Add custom win_git module that actually works 2023-07-27 22:09:45 +01:00
15 changed files with 149 additions and 1465 deletions

1194
git.py

File diff suppressed because it is too large Load Diff

View File

@@ -5,11 +5,12 @@
$module = [Ansible.Basic.AnsibleModule]::Create($args, @{
options = @{
dest = @{ type = 'path' }
repo = @{ required = $true; aliases = @( 'name' ) }
version = @{ default = 'HEAD' }
remote = @{ default = 'origin' }
executable = @{ default = $null; type = 'path' }
dest = @{type = 'path'}
repo = @{required = $true; aliases = @('name')}
version = @{default = 'HEAD'; aliases = @('branch')}
remote = @{default = 'origin'}
recursive = @{default = $true; type = 'bool'}
executable = @{default = $null; type = 'path'}
}
supports_check_mode = $false
})
@@ -19,25 +20,12 @@ $repo = $module.Params.repo
$version = $module.Params.version
$remote = $module.Params.remote
$git = $module.Params.executable
if ( !$git ) {
if (!$git) {
$git = Get-ExecutablePath 'git'
}
# ================================= Utilities ==================================
function Test-SshAcceptNewHostKey {
try {
$ssh = Get-ExecutablePath 'ssh'
} catch {
throw 'Remote host is missing ssh command, so you cannot use acceptnewhostkey option.'
}
$result = Run-Command "$ssh -o StrictHostKeyChecking=accept-new -V"
if ( $result.rc -ne 0 ) {
return $false
}
return $true
}
function Get-AbsolutePath {
[CmdletBinding()]
param (
@@ -58,70 +46,30 @@ function Get-GitDir {
)
$git_dir = Join-Path $path '.git'
# Check if this .git is a file.
if ( [System.IO.File]::Exists($git_dir) ) {
if ([System.IO.File]::Exists($git_dir)) {
# Extract the gitdir: path from the .git file.
$groups = Get-Content "$git_dir" | `
Select-String '(gitdir:) (.*)' | `
ForEach { $_.Matches[0].Groups[1..2] }
$ref_prefix = $groups[0]
$gitdir = $groups[1]
if ( $ref_prefix -ne 'gitdir:' ) {
if ($ref_prefix -ne 'gitdir:') {
$module.FailJson('The .git file has invalid gitdir reference format.')
}
# Check if the repo path is absolute.
if ( [System.IO.Path]::IsPathRooted($gitdir) ) {
if ([System.IO.Path]::IsPathRooted($gitdir)) {
$git_dir = $gitdir
} else {
# Join with the input path to construct an absolute path.
$git_dir = Join-Path $path $gitdir
}
if ( ![System.IO.Directory]::Exists($git_dir) ) {
if (![System.IO.Directory]::Exists($git_dir)) {
throw "$git_dir is not a directory."
}
}
return $git_dir
}
function Get-GitSshExecutablePath {
if ( $env:GIT_SSH ) {
return $env:GIT_SSH
}
if ( $env:GIT_SSH_COMMAND ) {
return $env:GIT_SSH_COMMAND
}
return Get-ExecutablePath 'ssh'
}
function Test-GitRemoteBranch {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $repository,
[Parameter(Mandatory = $true)] [String] $branch
)
$command = "`"$git`" ls-remote $repository -h refs/heads/$branch"
$result = Run-Command -command $command
if ( $result.stdout.Contains($version) ) {
return $true
}
return $false
}
function Test-GitRemoteTag {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $repository,
[Parameter(Mandatory = $true)] [String] $tag
)
$command = "`"$git`" ls-remote $repository -t refs/tags/$tag"
$result = Run-Command -command $command
if ( $result.stdout.Contains($version) ) {
return $true
}
return $false
}
function Test-GitLocalChanges {
[CmdletBinding()]
param (
@@ -135,79 +83,19 @@ function Test-GitLocalChanges {
return $changes.Lines -gt 0
}
function Get-GitRemoteHead {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)] [String] $repo,
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $version,
[Parameter(Mandatory = $true)] [String] $remote
)
$cloning = $false
$cwd = $null
$tag = $false
if ( $remote -eq $repo ) {
$cloning = $true
} else {
$cwd = $dest
}
if ( $version -eq 'HEAD' ) {
if ( $cloning ) {
# Cloning the repo, just get the remote's HEAD version.
$command = "`"$git`" ls-remote $remote -h HEAD"
} else {
$head_branch = Get-GitRemoteHeadBranch $module $dest $remote
$command = "`"$git`" ls-remote $remote -h refs/heads/$head_branch"
}
} elseif ( Test-GitRemoteBranch $dest $remote $version ) {
$command = "`"$git`" ls-remote $remote -h refs/head/$version"
} elseif ( Test-GitRemoteTag $dest $remote $version ) {
$tag = $true
$command = "`"$git`" ls-remote $remote -t refs/tags/$version*"
} else {
# Appears to be a sha1, return as-is since it apparently not possible
# to check for a specific sha1 on remote.
return $version
}
$result = Run-Command -command $command -working_directory $cwd
if ( $result.rc -ne 0 -or $result.stdout.Length -lt 1 ) {
throw "Could not determine remote ref for $vesion"
}
$ref = $result.stdout
if ( $tag ) {
# Find the dereferenced tag if this is an annotated tag.
ForEach ( $tag in $ref.Split([System.Environment]::NewLine) ) {
if ( $tag.EndsWith("$version ^{}") ) {
$ref = $tag
} elseif ( $tag.EndsWith($version) ) {
$ref = $tag
}
}
}
return $ref.Split()[0]
}
function Test-GitDetachedHead {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $dest
)
}
function Get-GitRemoteHeadBranch {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $version,
[Parameter(Mandatory = $true)] [String] $remote
)
$git_dir = Join-Path $dest '.git'
# TODO: Check if the .git is a file. If it is a file, it means that we are
# in a submodule structure.
$head_file = Join-Path $git_dir 'HEAD'
if ( Test-GitDetachedHead $dest ) {
$head_file = Join-Path $git_dir 'refs' 'remotes' $remote 'HEAD'
$command = "`"$git`" symbolic-ref --short refs/remotes/$remote/HEAD"
$result = Run-Command -command $command -working_directory $dest
if ($result.rc -ne 0) {
$module.FailJson("Could not determine the default HEAD branch of remote: $remote" ` +
"$result.stdout $result.stderr")
}
return $result.stdout.Trim().Replace("$remote/", '')
}
function Get-GitCurrentSha {
@@ -220,44 +108,6 @@ function Get-GitCurrentSha {
return $result.stdout.Trim()
}
function Get-GitRemoteUrl {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $remote
)
$command = "`"$git`" ls-remote --get-url $remote"
$result = Run-Command -command $command -working_directory $dest
if ( $result.rc -ne 0 ) {
# There was an issue getting the remote URL, most likely command is not
# available in this version of Git.
return $null
}
return $result.stdout.Trim()
}
function Set-GitRemoteUrl {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $remote,
[Parameter(Mandatory = $true)] [String] $url
)
# Return if remote URL isn't changing.
$remote_url = Get-GitRemoteUrl $dest $remote
if ( $remote_url -eq $repo ) {
return $false
}
$command = "`"$git`" remote set-url $remote $url"
$result = Run-Command -command $command -working_directory $dest
if ( $result.rc -ne 0 ) {
$module.FailJson("Failed to set a new url $url for $remote`: $result.stderr")
}
# Return false if remote_url is null to maintain previous behavior for Git
# versions prior to 1.7.5 that lack required functionality.
return $remote_url -ne $null
}
function Invoke-GitClone {
[CmdletBinding()]
Param (
@@ -266,15 +116,15 @@ function Invoke-GitClone {
[Parameter(Mandatory = $true)] [String] $dest
)
$dest_parent = Split-Path -Path $dest -Parent
if ( !(Test-Path $dest_parent) ) {
if (!(Test-Path $dest_parent)) {
New-Item -Path $dest_parent -ItemType Directory
}
$command = "`"$git`" clone --recursive --origin $remote $repo $dest"
if ( $version -ne "HEAD" ) {
if ($version -ne "HEAD") {
$command += " --branch $version"
}
$result = Run-Command -command $command -working_directory $cwd
if ( $result.rc -ne 0 ) {
if ($result.rc -ne 0) {
$module.FailJson($result.stderr)
}
# Ensure the newly cloned repository has the correct owner
@@ -287,38 +137,67 @@ function Invoke-GitClone {
}
}
function Invoke-GitFetch {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $repo,
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $version,
[Parameter(Mandatory = $true)] [String] $remote
)
$command = "`"$git`" fetch --tags $remote"
$result = Run-Command -command $command -working_directory $dest
if ( $result.rc -ne 0 ) {
$module.FailJson("Failed to download remote objects and refs:" + `
"$result.stdout $result.stderr")
}
}
function Invoke-GitCheckout {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $remote,
[Parameter(Mandatory = $true)] [String] $version
)
$result = Run-Command -command "`"$git`" checkout $version" -working_directory $dest
if ( $result.rc -ne 0 ) {
$module.FailJson("Failed to checkout version '$version': " + `
"$result.stdout $result.stderr")
if ($version -eq "HEAD") {
$branch = Get-GitRemoteHeadBranch $dest $remote
} else {
$branch = $version
}
$result = Run-Command -command "`"$git`" checkout $branch" -working_directory $dest
if ($result.rc -ne 0) {
$module.FailJson("Failed to checkout version '$version'`n" + $result.stderr)
}
}
function Invoke-GitFetch {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $remote,
[Parameter(Mandatory = $true)] [String] $version
)
$command = "`"$git`" fetch --tags $remote"
$result = Run-Command -command $command -working_directory $dest
if ($result.rc -ne 0) {
$module.FailJson("Failed to download remote objects and refs:`n" + `
$result.stderr)
}
}
function Invoke-GitPull {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $dest,
[Parameter(Mandatory = $true)] [String] $remote,
[Parameter(Mandatory = $true)] [String] $version
)
$result = Run-Command -command "`"$git`" pull $remote $version" -working_directory $dest
if ($result.rc -ne 0) {
$module.FailJson("Failed to pull version '$version' from remote '$origin':`n" + `
$result.stderr)
}
}
function Invoke-GitSubmoduleUpdate {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)] [String] $dest
)
$result = Run-Command -command "`"$git`" submodule update --init" -working_directory $dest
if ($result.rc -ne 0) {
$module.FailJson("Failed to initialized/update submodules:`n" + $result.stderr)
}
}
# ================================ Start logic =================================
if ( !$dest ) {
if (!$dest) {
$module.FailJson('The destination directory must be specified.')
}
$dest = Get-AbsolutePath $dest
@@ -327,18 +206,26 @@ $gitconfig = Join-Path $git_dir 'config'
$module.Result.before = $null
$local_changes = $false
if ( ($dest -and ![System.IO.File]::Exists($gitconfig)) -or (!$dest -and !$clone) ) {
Invoke-GitClone $repo $remote $dest $version
if (($dest -and ![System.IO.File]::Exists($gitconfig))) {
Invoke-GitClone $repo $remote $dest
Invoke-GitCheckout $dest $remote $version
$module.Result.changed = $true
} else {
$local_changes = Test-GitLocalChanges $dest
$module.Result.before = Get-GitCurrentSha $dest
if ( $local_changes ) {
if (Test-GitLocalChanges $dest) {
$module.FailJson('Local modifications exist in repository.')
}
# Checkout branch, if $version is HEAD get HEAD branch
# Pull
Invoke-GitFetch $dest $remote $version
Invoke-GitCheckout $dest $remote $version
Invoke-GitPull $dest $remote $version
$module.Result.after = Get-GitCurrentSha $dest
if ($module.Result.before -ne $module.Result.after) {
$module.Result.changed = $true
}
}
if ($recursive) {
Invoke-GitSubmoduleUpdate $dest
}
$module.ExitJson()

View File

@@ -2,6 +2,6 @@
- hosts: localhost
roles:
- role: 1password
- role: ferdium
- role: fonts
- role: obsidian
- role: webcatalog

View File

@@ -4,3 +4,4 @@
roles:
- role: gdb
- role: wsl
- role: system-info

View File

@@ -23,7 +23,9 @@
- role: 1password
- role: autohotkey
- role: ferdium
- role: firefox
- role: fonts
- role: obsidian
- role: powertoys
- role: windows-terminal

View File

@@ -11,36 +11,21 @@
path: '{{app_exe}}'
register: app_stat
- name: get installed version
when: app_stat.stat.exists == True
win_command: '{{app_exe}} --version'
register: app_version
changed_when: false
- when: app_stat.stat.exists == True
set_fact:
installed_version: '{{app_version.stdout.strip()}}'
- name: download latest installer
when: not app_stat.stat.exists
win_get_url:
url: https://downloads.1password.com/win/1PasswordSetup-latest.exe
dest: '{{installer_exe}}'
- name: get installer version
win_shell: |
(Get-ItemProperty {{installer_exe}}).VersionInfo.ProductVersion
register: installer_product_version
changed_when: false
# FIXME: The [5:] is to account for a mystery "\e[6 q" prefix, not sure if this
# is consistent across machines or some other oddity.
- set_fact:
installer_version: '{{installer_product_version.stdout.strip()[5:]}}'
- name: run installer
when: installed_version is not defined or installed_version != installer_version
when: not app_stat.stat.exists
win_command: '{{installer_exe}}'
- name: remove installer
win_file:
path: '{{installer_exe}}'
state: absent
- name: create start menu shortcut
win_shortcut:
src: '{{app_exe}}'

View File

@@ -0,0 +1,17 @@
---
- name: install homebrew package
when: ansible_os_family == 'Darwin'
homebrew_cask:
name: ferdium
state: latest
- when: ansible_os_family == 'Windows'
win_chocolatey:
name: ferdium
state: latest
- name: install flatpak package
when: ansible_os_family != 'Windows' and
ansible_os_family != 'Darwin'
flatpak:
name: org.ferdium.Ferdium

View File

@@ -0,0 +1,5 @@
---
- name: install chocolatey package
win_chocolatey:
name: nerd-fonts-CascadiaCode
state: latest

View File

@@ -1,5 +1,7 @@
---
- when: ansible_os_family == 'Darwin'
include_tasks: 'Darwin.yaml'
- when: ansible_os_family == 'Windows'
include_tasks: 'Windows.yaml'
- when: ansible_os_family != 'Darwin' and ansible_os_family != 'Windows'
include_tasks: 'Linux.yaml'

View File

@@ -31,17 +31,12 @@
- include_tasks: Windows-installer.yaml
when: git_run_installer
# - name: clone config repos
# win_git:
# repo: '{{item.repo}}'
# dest: '{{ansible_env.USERPROFILE}}\.config\{{item.name}}'
# version: master
# with_items: '{{git_config_repos}}'
# - win_owner:
# path: '{{ansible_env.USERPROFILE}}\.config\{{item.name}}'
# user: Benie
# recurse: true
# with_items: '{{git_config_repos}}'
- name: clone config repos
win_git:
repo: '{{item.repo}}'
dest: '{{ansible_env.USERPROFILE}}/.config/{{item.name}}'
version: master
with_items: '{{git_config_repos}}'
# - TODO: install pip packages
# win_pip:

View File

@@ -26,6 +26,13 @@
file_type: directory
register: found_plugins
- set_fact:
backslashes: '\\'
forwardslash: '/'
- set_fact:
managed_plugins: "{{managed_plugins | replace(backslashes, forwardslash)}}"
found_plugins: "{{found_plugins | replace(backslashes, forwardslash)}}"
- name: remove found plugins which are not in the managed list
win_file:
path: '{{item.path}}'

View File

@@ -8,17 +8,11 @@
- set_fact:
vim_config_dir: '{{ansible_env.LOCALAPPDATA}}\nvim'
# - name: clone config repo
# win_git:
# repo: git@code.infektor.net:config/vim.git
# dest: '{{vim_config_dir}}'
# branch: master
# # clone: false
# update: true
# - win_owner:
# path: '{{vim_config_dir}}'
# user: Benie
# recurse: true
- name: clone config repo
win_git:
repo: git@code.infektor.net:config/vim.git
dest: '{{vim_config_dir}}'
branch: master
# - TODO: neovim set repo email
# win_git_config:
@@ -47,10 +41,18 @@
src: '{{vim_config_dir}}/tasks.yaml'
dest: vim_config_tasks.yaml
flat: true
changed_when: false
- when: config_repo_tasks.stat.exists
include_tasks: vim_config_tasks.yaml
- name: remove fetched tasks
file:
state: absent
path: vim_config_tasks.yaml
changed_when: false
delegate_to: localhost
- when: ansible_os_family != "Windows" and
plugin_dir is defined and plugins is defined
include_tasks: 'Unix-plugins.yaml'

View File

@@ -3,7 +3,7 @@ Name=Obsidian
Exec={{ansible_env.HOME}}/.local/bin/Obsidian
Terminal=false
Type=Application
Icon=obsidian
Icon={{ansible_env.HOME}}/.local/{{iconpath}}
StartupWMClass=Obsidian
X-AppImage-Version={{latest.json.name}}
Comment=Private and flexible notetaking app that adapts to the way you think.

View File

@@ -5,13 +5,9 @@
- name: clone config repos
win_git:
repo: git@code.infektor.net:config/WindowsPowerShell.git
repo: https://code.infektor.net/config/WindowsPowerShell.git
dest: '{{powershell_config_dir}}'
branch: master
- win_owner:
path: '{{powershell_config_dir}}'
user: Benie
recurse: true
- name: install chocolatey package
win_chocolatey:

View File

@@ -1,5 +1,6 @@
---
- name: create wsl.conf
become: true
template:
src: templates/wsl.conf.j2
dest: /etc/wsl.conf
@@ -34,28 +35,6 @@
dest: external
state: directory
- name: clone ansible win_git module
git:
repo: https://github.com/tivrobo/ansible-win_git.git
dest: external/ansible-win_git
version: master
- set_fact:
modules_dir: ~/.config/local/modules
- name: create ansible modules directory
file:
dest: '{{modules_dir}}'
state: directory
- name: copy win_git files to ansible modules directory
copy:
src: '~/.config/local/external/ansible-win_git/{{item}}'
dest: '{{modules_dir}}/{{item}}'
with_items:
- win_git.ps1
- win_git.py
- name: read /etc/resolv.conf file contents
set_fact:
resolv_conf: '{{lookup("ansible.builtin.file", "/etc/resolv.conf")}}'