Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
39c81cd
add go project generated from `go-copier`
MrPointer Mar 27, 2025
4e292c1
fix go's `.gitignore` to ignore generated artifacts
MrPointer Mar 27, 2025
e144414
add a compatibility config that's embedded in the binary
MrPointer Mar 28, 2025
8b7be60
add an OS compatibility check for the dotfiles
MrPointer Mar 28, 2025
f48e305
add a cobra-based cli app with a `check-compatibility` command
MrPointer Mar 28, 2025
993261e
add placeholder for `install` command
MrPointer Apr 26, 2025
1a9afce
vscode: add prompt for installer context when working on it
MrPointer Apr 26, 2025
fca509e
add abstract logger to log when applicable
MrPointer Apr 26, 2025
6bde360
collect system info when checking for compatibility
MrPointer Apr 26, 2025
f81384f
add ability to install brew via go installer
MrPointer Apr 26, 2025
16ea20e
add ability to log debug statements
MrPointer May 10, 2025
6ad10c5
add commander interface to allow running commands differently
MrPointer May 10, 2025
ab4726a
vscode: set flags for go tests
MrPointer May 10, 2025
83399ec
refactor brew package to be more robust and idiomatic go
MrPointer May 10, 2025
cc94549
separate unit & integration tests for brew
MrPointer May 11, 2025
2cd9557
self-validate brew is installed correctly as part of installation
MrPointer May 11, 2025
978ed1b
make multi-user brew install more robust
MrPointer May 11, 2025
ea73a45
vscode: add copilot instructions for go code
MrPointer May 11, 2025
f8ebcd5
move stuff out of installer-context prompt into the instructions
MrPointer May 11, 2025
2e01b58
space out code for brew package
MrPointer May 11, 2025
81ca980
copilot: update instructions to use `testify` for testing
MrPointer May 17, 2025
211bf41
move brew's unit tests into the test package
MrPointer May 17, 2025
2d2482f
use mockery for generating mock objects in tests
MrPointer May 30, 2025
44a02af
add filesystem interface to decouple code from raw file operations
MrPointer May 30, 2025
78961b1
add httpclient interface to decouple code from raw http requests
MrPointer May 30, 2025
74ad427
add os-manager interface to decouple code from raw os calls
MrPointer May 30, 2025
831e506
increase testability of the `brew` package by injecting dependencies
MrPointer May 30, 2025
b84845c
finalize decoupling by abstracting file permission settings
MrPointer May 30, 2025
eb01501
rewrite copilot instruction files to make them LLM compatible
MrPointer May 31, 2025
30e5c59
add `testify` dependency
MrPointer May 31, 2025
854b082
add comprehensive unit tests to brew installation
MrPointer May 31, 2025
370df7a
copilot: adjust testing instructions
MrPointer May 31, 2025
302669d
add copier answers file to allow updates from remote
MrPointer Jun 3, 2025
6f5ff07
update go installer template against latest
MrPointer Jun 3, 2025
a3cc6f1
fix all golangci-lint warnings
MrPointer Jun 4, 2025
4a7d861
add ability to check existance of gpg suite
MrPointer Jun 4, 2025
4d1d55e
move brew installer to better named file
MrPointer Jun 6, 2025
04f412f
refactor `Commander` to allow flexibility
MrPointer Jun 6, 2025
6df6eda
fix failing brew tests
MrPointer Jun 14, 2025
e0499db
unignore embedded config files
MrPointer Jun 14, 2025
3746a35
move brew integration test closer to package
MrPointer Jun 14, 2025
001f4c4
add package manager mapping system with YAML config and resolver
MrPointer Jun 14, 2025
49d387f
add Homebrew package manager implementation and tests
MrPointer Jun 20, 2025
0bda328
rename `os_manager` file to `osmanager`
MrPointer Jun 20, 2025
21014c1
initialize all abstractions globally
MrPointer Jun 20, 2025
7083163
add GPG client installation via package manager
MrPointer Jun 20, 2025
44fcfa6
improve error logging in `install` sub-command
MrPointer Jun 20, 2025
04b088f
rename gpg client files to installer files
MrPointer Jun 21, 2025
944db91
add GPG client implementation with tests
MrPointer Jun 22, 2025
67a0620
add interactive GPG key selection using huh selector
MrPointer Jun 22, 2025
22550bd
add interactive mode flag to install command
MrPointer Jun 24, 2025
a4d79a2
add shell installation step
MrPointer Jun 24, 2025
74ad5e5
remove unnecessary `systemInfo` member of gpg installer
MrPointer Jun 24, 2025
d5ede1d
Create cspell.json
MrPointer Jun 24, 2025
28f27a7
exclude cli from mockery
MrPointer Jul 17, 2025
514ddd7
add dependency on mo's optional
MrPointer Jul 17, 2025
f5778a6
add dotfiles data initializer
MrPointer Jul 17, 2025
10e7dba
add method to create dir with permissions
MrPointer Jul 17, 2025
64d3f0e
update cspell dictionary
MrPointer Jul 20, 2025
4940ba0
add tests for chezmoi data initializer
MrPointer Jul 22, 2025
2cb6036
combine chezmoi applier and initializer into single `manager`
MrPointer Jul 22, 2025
7a50185
update `ChezmoiManager` constructor to accept config object
MrPointer Jul 22, 2025
5dabf62
implement `apply()` for chezmoi manager
MrPointer Jul 22, 2025
276b748
add an installer for chezmoi
MrPointer Jul 22, 2025
c46e5a2
reorder function declaration to match call order
MrPointer Jul 22, 2025
9515ae9
setup dotfiles manager in `install` cli command
MrPointer Jul 25, 2025
b38304d
add prerequisite checks to compatibility system
MrPointer Jul 25, 2025
8abeb65
generate missing mocks with mockery
MrPointer Jul 25, 2025
b1f04ec
display hints for missing prerequisites
MrPointer Jul 25, 2025
9f479a3
add smart privilege escalation utility
MrPointer Jul 26, 2025
b9c11d1
add package manager impl for apt
MrPointer Jul 26, 2025
778e86d
allow opt-in automatic install of system prerequisites
MrPointer Jul 26, 2025
c52de90
use absolute path when invoking brew
MrPointer Jul 26, 2025
1583e80
ensure chezmoi config file can be written to on data init
MrPointer Jul 26, 2025
527f995
update system path to include brew after installation
MrPointer Jul 26, 2025
c1ca49d
make brew output less verbose when listing packages
MrPointer Jul 26, 2025
0f3c8f5
fix chezmoi's config file path not being nested
MrPointer Jul 26, 2025
5f31580
align dotfiles system data struct to existing format
MrPointer Jul 26, 2025
7067dfb
fill dotfiles system data in install command
MrPointer Jul 26, 2025
2d8896d
support interactive installation of prerequisites
MrPointer Aug 2, 2025
9760cf8
log debug statements only when verbose
MrPointer Aug 9, 2025
c934a30
fix segfault due to wrong init order
MrPointer Aug 9, 2025
d5352b7
fix gpg key creation in tough environments
MrPointer Aug 9, 2025
c397e4b
fix gpg key extraction for newly created keys
MrPointer Aug 10, 2025
5a447b3
add trace logging, cli option to increase verbosity
MrPointer Aug 10, 2025
6bb14e2
add detailed logging to all dotfiles actions
MrPointer Aug 11, 2025
c3c21c0
add detailed logging to package managers
MrPointer Aug 11, 2025
2f02fa2
use trace for extra-detailed logging in gpg client
MrPointer Aug 11, 2025
6036693
imrpove logging for all installers
MrPointer Aug 11, 2025
a5df496
change default git clone protocol to https
MrPointer Aug 15, 2025
1a31656
fill missing chezmoi data vars regarding work
MrPointer Aug 15, 2025
9c52dc2
add hierarchal spinner-progress output
MrPointer Aug 16, 2025
7cfa91d
overhaul log-affecting cli flags
MrPointer Aug 16, 2025
4777cd2
replace `progress` cli option with `plain`
MrPointer Aug 16, 2025
309cb82
fix tests to use default logger instead of mock
MrPointer Aug 17, 2025
577374a
updating logging in installer to match progress report
MrPointer Sep 20, 2025
9805f3e
improve nested progress reports
MrPointer Sep 23, 2025
e00a4a2
add custom docker files per distro for testing
MrPointer Sep 23, 2025
66ffbee
support interactive progress trackers
MrPointer Sep 24, 2025
fc5424a
support progress cleanup when finalizing
MrPointer Sep 24, 2025
5092a02
improve progress reporter impl and logger interop
MrPointer Sep 24, 2025
9a22c8e
fix races in progress reporter
MrPointer Sep 24, 2025
9426f1d
add unit tests for pausing/resuming progress
MrPointer Sep 25, 2025
17acf09
improve naming of logger tests, make them unit tests
MrPointer Sep 25, 2025
a9e875c
discard underlying tool output in interactive sessions
MrPointer Sep 25, 2025
61d4764
fix broken gpg client tests
MrPointer Sep 27, 2025
bfbc549
make sure brew is available for mac early
MrPointer Sep 27, 2025
5bcfa5f
lower log level of os-manager operations
MrPointer Sep 27, 2025
8abfbcc
Revert "fix broken gpg client tests"
MrPointer Sep 27, 2025
58313c2
fix regression caused by AI in gpg client
MrPointer Sep 27, 2025
5f25e99
lower log level of package-managers version warning
MrPointer Sep 27, 2025
c2971a3
fix compatibility map to work with our program query
MrPointer Oct 14, 2025
f5ec2c3
ci: add github-actions workflow
MrPointer Oct 14, 2025
99431a5
remove ci files of the original go template
MrPointer Oct 14, 2025
aac4f4d
ci: set working dir explicitly for installer steps in CI
MrPointer Oct 14, 2025
720a814
ci: customize build artifacts upload rules
MrPointer Oct 17, 2025
d328076
fix race condition in progress logger tests
MrPointer Oct 17, 2025
aeb3784
update all dependencies to latest versions
MrPointer Oct 17, 2025
42fadc5
fix apt installer integration tests
MrPointer Oct 17, 2025
040bcb9
ci: rename test job to `Test`
MrPointer Oct 17, 2025
3d5f752
ci: fix binary path used in e2e tests
MrPointer Oct 17, 2025
904f6b7
ci: remove e2e test for binary version
MrPointer Oct 17, 2025
4248dcd
ci: enable verbose output for install command
MrPointer Oct 17, 2025
f6cb94e
ci: adjust prerequisite setup step for e2e tests
MrPointer Oct 17, 2025
48ca02d
ci: install prerequisites automatically in e2e tests
MrPointer Oct 17, 2025
1bcaca3
ci: conditionally fail compatibility check e2e test
MrPointer Oct 17, 2025
5605168
add interactive automation script using expect
MrPointer Oct 17, 2025
930310f
ci: add step to e2e test to check interactive mode
MrPointer Oct 17, 2025
6c8f7c2
ci: be unforgiving in tests, let them fail naturally
MrPointer Nov 21, 2025
3376e45
fix chezmoi application failure on macos
MrPointer Nov 21, 2025
6b497a2
task: make test task not depend on source files
MrPointer Nov 21, 2025
4b5fd2d
pass `--config` option to chezmoi when applying
MrPointer Nov 21, 2025
40e8ce4
update readme to fit new Go installer
MrPointer Nov 22, 2025
dc223cf
remove deprecated shell installers
MrPointer Nov 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions .github/INSTALLER_CI_README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Installer CI Documentation

This directory contains GitHub Actions workflows for the dotfiles installer project located in the `installer/` subdirectory.

## Workflow Overview

### 🔧 installer-ci.yml
**Purpose**: Build and test the installer
**Trigger**: Push to main or PRs affecting `installer/` directory

**Jobs (in order)**:
1. **Build**: Uses GoReleaser to create cross-platform binaries
2. **Test**: Runs Go test suite with race detection
3. **E2E Tests**: Tests installer on multiple platforms in real environments

**Platforms Tested**:
- Ubuntu (latest)
- Debian (bookworm container)
- macOS (latest)

## Build Process

The CI uses GoReleaser in **snapshot mode** to:
- Build cross-platform binaries (Linux/macOS, AMD64/ARM64)
- Generate consistent build artifacts
- **No releases** - just builds for testing

## E2E Testing

The pipeline includes end-to-end testing that:

1. **Downloads** the built installer binary
2. **Tests** on multiple OS distributions
3. **Verifies** compatibility detection works
4. **Runs** installer in non-interactive mode
5. **Validates** graceful behavior in CI environments

### Test Configuration

E2E tests use these flags for CI compatibility:
- `--non-interactive`: Skips all user prompts
- `--plain`: Disables progress indicators for cleaner logs
- `--install-brew=false`: Skips Homebrew for faster testing
- `--install-prerequisites=false`: Skips prerequisite installation
- `--git-clone-protocol=https`: Uses HTTPS instead of SSH

### Test Environment

- **Isolated**: Uses `/tmp/test-home` as HOME directory
- **Timeout**: 300 seconds (5 minutes) to prevent hangs
- **Graceful Failures**: Expected in CI since we don't have full system setup

## Local Testing

To test the workflow locally:

```bash
cd installer/
task build
./bin/dotfiles-installer install --non-interactive --plain --install-brew=false
```

## Workflow Structure

```
.github/
└── workflows/
└── installer-ci.yml # Main CI pipeline
```

## Troubleshooting

### Common Issues

1. **Build Fails**: Check Go version in `installer/go.mod`
2. **E2E Test Fails**: Review platform-specific requirements
3. **Test Timeout**: E2E tests timeout after 5 minutes

### Debugging E2E Tests

E2E tests are designed to handle CI environment limitations:
- Allow expected failures (exit code 1) in restricted environments
- Create isolated test directories
- Skip complex system modifications

To debug locally:
```bash
export HOME="/tmp/test-home"
mkdir -p "$HOME"
./installer/bin/dotfiles-installer install --non-interactive --plain
```

## Future Enhancements

- **Linting**: Will integrate golangci-lint later
- **Security Scanning**: Can add Trivy scans if needed
- **Release Automation**: Will add when ready for releases
38 changes: 38 additions & 0 deletions .github/instructions/go-code-style.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
applyTo: "**/*.go"
---

# Go Coding Style

## General Guidelines

- Use the Go standard library whenever possible. Only use third-party libraries when necessary.
- Limit line length to 120 characters.
- Write code that is easy to test:
- Use interfaces to decouple components and improve testability.
- Use dependency injection to pass dependencies into functions and methods.
- Wrap even basic operations (such as OS functions and file operations) in interfaces to make them easier to mock and test.
- After each struct definition, verify interface implementation by adding:
`var _ InterfaceName = (*StructName)(nil)`
- Provide a constructor function for each struct, named `NewStructName`.
- Place this function immediately after the struct definition and the interface assertion line (if present).
- Format code for readability:
- Vertically align function arguments when there are multiple arguments.
- Insert blank lines between logical sections of code.
- Do not separate error unwrapping from related code with a blank line; treat it as part of the same section.
- End all type and function comments with a period, following Go conventions.
- Pre-allocate collections (such as slices and maps) to their expected size when possible to reduce memory allocations and improve performance.

## Main Tech Stack

- [lipgloss]: Go library for creating visually appealing command-line applications. Used for the installer's CLI.
- [cobra]: Go library for building command-line applications. Used for the installer's CLI.
- [viper]: Go library for reading configuration files. Used for the installer's configuration management.
- [goreleaser]: Go tool for building and releasing Go applications. Used for building and releasing the installer.
- [gh-actions] (GitHub Actions): CI/CD tool for automating build and release processes. Used for building and releasing the installer.

[lipgloss]: https://github.com/charmbracelet/lipgloss
[cobra]: https://github.com/spf13/cobra
[viper]: https://github.com/spf13/viper
[goreleaser]: https://github.com/goreleaser/goreleaser
[gh-actions]: https://github.com/features/actions
51 changes: 51 additions & 0 deletions .github/instructions/go-test-style.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
applyTo: "**/*.go"
---

# Go Test Style

## General Guidelines

- Place tests in the test package of the package being tested.
- For example, if the package is `lib`, the test package should be named `lib_test`.
- Use the `testify` library for all testing in Go.
- Always use the `require` package from `testify` when checking the `error` type.
- Each test should verify a single behavior or property. Do not test multiple behaviors in a single test.
- Name tests based on their behavior, using descriptive and natural language.
- Example: `Test_CompatibilityConfigCanBeLoadedFromFile` checks if the `CompatibilityConfig` struct can be loaded from a file.
- Test names should describe what the test does and what it verifies, not implementation details.
- Use the `Test_` prefix for test functions.
- If a condition is crucial to the test, include it in the test name.
- Example: `Test_CompatibilityConfigCanBeLoadedFromFile_WhenFileExists` indicates that the test checks loading from an existing file.
- Separate different conditions with underscores.
- Use table-driven tests when appropriate. Table-driven tests define a set of inputs and expected outputs in a table, and iterate over the table to run the tests. This pattern makes it easy to add new test cases and keeps the code clean and maintainable.

## Types of Tests

### Unit Tests

- Unit tests verify a single function or method in isolation.
- Use mocks to isolate the function or method being tested.
- Use the [moq](https://github.com/matryer/moq) package to generate mocks.

### Integration Tests

- Integration tests verify the interaction between multiple functions or methods.
- Integration tests also cover OS-dependent interactions (anything beyond CPU and memory).
- For every integration test, allow opting out by using `testing.Short()`.
- This is useful for running only unit tests in CI/CD pipelines.

## Testing Tech Stack

- [testify]: A Go library for writing tests and assertions.
- [moq]: A Go library for generating mocks for testing.
- [mockery]: A Go library for generating mock objects. It is used to generate mock objects in the project.

## Using Mocks

- Use [mockery] to generate mocks for interfaces. Run the command `mockery` (with no arguments) in the root directory of the Go module (for example, the `go-port` directory).
- In test code, use the generated mocks to test your code. The generated mocks are compatible with the `moq` library, so you can use `moq` features in your tests.

[testify]: https://github.com/stretchr/testify
[moq]: https://github.com/matryer/moq
[mockery]: https://github.com/vektra/mockery
51 changes: 51 additions & 0 deletions .github/prompts/installer-context.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Prompt for working on the installer

## General Instructions

- You're an expert in Operating Systems, UNIX shells, and Go.
- You're passionate about dotfiles.
- You specialize in configuration management and automation.

## Context

### What is this repository?

This repository is my personal dotfiles repository. It uses [chezmoi][chezmoi] to manage dotfiles
and configurations across multiple machines. The goal is to have a consistent and easily maintainable setup.
It also contains an "installer" to bootstrap the dotfiles on a new machine, as [chezmoi][chezmoi] alone is
not enough to set up a new machine.

### What is the installer?

Currently, there are two types of installers:

1. **Shell Installer**: A shell script that installs the necessary dependencies and sets up the environment.
2. **Go Installer**: A Go program that does the same thing as the shell installer but is written in Go.

This is temporary as the goal is to move the shell installer to Go. The shell installer is
currently the main installer, but the Go installer is being developed to replace it.

### How does the shell installer works?

The shell installer is a 2-step process:

1. Bootstrap script: This script is run first as it is written in POSIX shell and can be run on any
platform. It installs the absolute minimum dependencies required to run the main installer,
and checks for compatibility. It is located at [`install.sh`](../../install.sh).
2. Main installer: This is the main installer that installs the necessary dependencies and sets up
the environment. It is located at [`install-impl.sh`](../../install-impl.sh).
It is written in bash 4.

### What is the goal of the installer?

The goal of the installer is to set up a new machine with the necessary dependencies and configurations
to run the dotfiles. This includes installing [chezmoi][chezmoi], setting up the environment, and
configuring the shell. The installer should be easy to use and should work on multiple platforms (Linux, macOS, etc.).
The installer should also be able to detect the platform and install the necessary dependencies accordingly.

## What should you do?

Analyze the current state of the installer to understand how much of it has been ported to Go.
Then, ask me what I want to do next.

[chezmoi]: https://chezmoi.io/
Loading
Loading