Skip to content
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
27294b8
chore(repo): expand .gitignore for multi-os dev
jonrandahl Feb 16, 2026
c8b890c
fix(logging): handle non-integer request_time
jonrandahl Feb 16, 2026
6d8efe3
fix(logging): report request params correctly
jonrandahl Feb 16, 2026
c79676a
refactor(logging): clarify completed request message
jonrandahl Feb 16, 2026
2f908c6
feat(logging): derive level from status code
jonrandahl Feb 16, 2026
11ab6ac
build(make): unify targets for dev workflow
jonrandahl Feb 16, 2026
d40227f
chore(deps): add maint group, drop meta_request
jonrandahl Feb 17, 2026
ab8e600
chore(deps): upgrade rails to 8.1.2 via railties
jonrandahl Feb 17, 2026
c6080b4
chore(deps): bump debug to 1.11.1
jonrandahl Feb 17, 2026
8ff5268
chore(dev-deps): update linter/parser toolchain
jonrandahl Feb 17, 2026
8e1eab6
test(coverage): enable SimpleCov for test runs
jonrandahl Feb 17, 2026
a41ef0c
docs(changelog): adopt Keep a Changelog and SemVer
jonrandahl Feb 17, 2026
96ef916
docs(changelog): record 2.3.0 logging improvements
jonrandahl Feb 17, 2026
be6f4a2
chore(version): bump to 2.3.0
jonrandahl Feb 17, 2026
5461369
build(deps): bump logging gem to 2.3.0
jonrandahl Feb 17, 2026
a9417d0
fix(logging): keep level when HTTP status unknown
jonrandahl Feb 18, 2026
45c7161
style(logging): prioritise ts and level in log JSON
jonrandahl Feb 18, 2026
a38ee78
fix(logging): handle nil severity; trim level
jonrandahl Feb 19, 2026
54ae071
test(formatter): use thread-local request id
jonrandahl Feb 19, 2026
e3fbeda
refactor(logging): streamline completion message
jonrandahl Feb 19, 2026
47f602a
feat(logging): make optional fields opt-in
jonrandahl Feb 19, 2026
53977fe
test(formatter): cover optional and nil severity
jonrandahl Feb 20, 2026
e7eedee
docs(changelog): update logging improvements
jonrandahl Feb 20, 2026
34fd425
feat(githooks): update to unified lint/test/push hooks
jonrandahl Feb 20, 2026
388ffe9
fix(logging): call parent initialiser
jonrandahl Feb 20, 2026
7e3ffeb
refactor(formatter): extract message key partition
jonrandahl Feb 24, 2026
5c74b79
feat(logger): expose include_optional option
jonrandahl Feb 24, 2026
4cd81cc
docs(readme): document railtie and optional fields
jonrandahl Feb 24, 2026
bc968ef
docs(readme): update developer setup command
jonrandahl Feb 24, 2026
e7ecca6
build(deps): tighten logging dependency ranges
jonrandahl Feb 24, 2026
734bc17
docs(logging): add rich YARD docs for JSON logger
jonrandahl Feb 24, 2026
7f3d753
build(make): add yard docs target
jonrandahl Feb 24, 2026
dba4272
docs(readme): clarify formatter; add make targets
jonrandahl Feb 24, 2026
a30e1d0
docs(metadata): clarify gem is a log formatter
jonrandahl Feb 24, 2026
6e2b427
fix(formatter): keep duration; support symbol keys
jonrandahl Feb 24, 2026
dd61680
test(middleware): cover request id handling
jonrandahl Feb 24, 2026
8bf9925
test(middleware): restore original Rails constant
jonrandahl Feb 25, 2026
1825cf8
refactor(logging): rename optional to ignored
jonrandahl Feb 25, 2026
8f0b014
refactor(logging): normalise timing and unify key
jonrandahl Feb 25, 2026
262abf1
fix(logging): respect explicit log level
jonrandahl Feb 25, 2026
3b5d243
ci(docs): publish versioned YARD docs on Pages
jonrandahl Feb 25, 2026
08939d1
docs(changelog): add YARD docs and Railties 8.1.2
jonrandahl Feb 25, 2026
da27513
docs(changelog): remove log-level normalisation
jonrandahl Feb 26, 2026
2142a90
ci(workflows): split release and wire version output
jonrandahl Feb 26, 2026
0f935a4
docs(readme): clarify usage and add API docs
jonrandahl Feb 26, 2026
1448624
docs(logging): remove stale ignored fields section
jonrandahl Feb 26, 2026
0dd696f
refactor(logging): ensure processing ignored keys always returns message
jonrandahl Mar 3, 2026
753e10a
fix(formatter): Correct request URI message placement
jonrandahl Mar 3, 2026
930521a
feat(deps): Broaden gem dependency constraints
jonrandahl Mar 3, 2026
68d3335
chore(deps): Constrain runtime dependency versions
jonrandahl Mar 3, 2026
1d551e4
Remove GitHub Pages docs deployment workflow
jonrandahl Mar 3, 2026
47dc342
ci(publish): clarify gem publish step
jonrandahl Mar 3, 2026
693d1e1
ci(publish): Corrects typo
jonrandahl Mar 3, 2026
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
46 changes: 46 additions & 0 deletions .githooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Now using githooks for automation

- Pre-commit hook will lint Ruby files before committing and reset[^*] if fails.
- Post-commit hook will run tests after committing and reset[^*] if fails.
- Pre-push hook to build and verify Gem construction and prevent push if fails.
- Allows skipping of hooks on specific branches:
- `hotfix`
- `rebase`
- `production`
- You can also manually skip hooks using the `--no-verify` flag on any branch
commit:

```sh
git commit --no-verify -m "skipping hooks on this commit"
```

or

```sh
git push --no-verify
```

## Setup

Use the following commands to enable the hooks to initiate hooks onto your local
copy of the repository, otherwise the hooks will not be triggered to run
automatically:

1. set the path to the hooks in the repository gitconfig:

```sh
git config core.hooksPath '.githooks'
```

2. set permissions for the hooks:

```sh
chmod +x .githooks/pre-commit .githooks/post-commit .githooks/pre-push
```

### Additional information

- <https://github.com/epimorphics/githooks/blob/main/README.md>
- <https://git-scm.com/docs/githooks>

[^*]: instructs reset to find the first parent ref of `HEAD`
79 changes: 79 additions & 0 deletions .githooks/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash
# Common utilities and functions for git hooks
#
# Environment variables:
# NO_COLOR - Set to any value to disable colored output (e.g., NO_COLOR=1 git commit)

# Check if color output is disabled (set NO_COLOR=1 to disable)
: "${NO_COLOR:=}"

# Initialize branch name from filtered branch list
init_branch_name() {
local list="issue spike task"
local listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/"

BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //')
}

# Check if hook should be skipped based on branch, reflog action, or flags
should_skip_hook() {
# Skip on specific branches
if echo "$BRANCH_NAME" | grep -qE '^(hotfix|rebase|prod(uction)?)$'; then
return 0
fi

# Skip if Git reflog indicates an amend (reliable for GUI flows)
if [ "${GIT_REFLOG_ACTION:-}" = "commit (amend)" ]; then
return 0
fi

# Fallback: check parent process for --no-verify or --amend flags
local ppid_cmd
ppid_cmd=$(ps -ocommand= -p $PPID 2>/dev/null || echo "")
if [[ "$ppid_cmd" == *"--no-verify"* ]] || [[ "$ppid_cmd" == *"--amend"* ]]; then
return 0
fi

return 1
}

# Print colored status messages (respects NO_COLOR environment variable)
print_header() {
if [ -z "$NO_COLOR" ]; then
printf '\n\033[0;105m%s\033[0m\n' "$1"
else
printf '\n%s\n' "$1"
fi
}

print_success() {
if [ -z "$NO_COLOR" ]; then
printf '\n\033[0;32m%s\033[0m\n' "$1"
else
printf '\n%s\n' "$1"
fi
}

print_warning() {
if [ -z "$NO_COLOR" ]; then
printf '\n\033[0;33m%s\033[0m\n' "$1"
else
printf '\n%s\n' "$1"
fi
}

print_error() {
if [ -z "$NO_COLOR" ]; then
printf '\n\033[0;31m%s\033[0m\n' "$1"
else
printf '\n%s\n' "$1"
fi
}

print_info() {
if [ -z "$NO_COLOR" ]; then
printf '\033[0;33m%s\033[0m\n' "$1"
else
printf '%s\n' "$1"
fi
}
70 changes: 70 additions & 0 deletions .githooks/post-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/bin/bash
# This hook is called by "git commit" after the commit message editor
# is closed. The default behavior is to run the tests and if they pass,
# the commit is allowed to proceed. If the tests fail, the commit is
# aborted. The hook can be bypassed by using the --no-verify option
# when running "git commit".

# Source common hook utilities
. "$(dirname "$0")/common.sh"

# Initialize branch name
init_branch_name

print_header "Checking \"$BRANCH_NAME\"..."

# Skip if on specific branches, or when amending or --no-verify flag is set
if should_skip_hook; then
print_warning "Skipping post-commit hook... 🤨"
exit 0
fi

# Check for existence of "new or modified" test files
NEW_TEST_FILES="$(git diff --diff-filter=ACDM --name-only --cached | grep -E '(./test/*)$')"
# Get all test files to run tests
CURRENT_TEST_FILES="$(git ls-files | grep -i -E '(_test\.rb)$')"

RAILS_TEST_EXIT_CODE=0
WORK_DONE=0

if [ -n "$NEW_TEST_FILES" ]; then
#Count the number of new test files
file_count=$(echo "$NEW_TEST_FILES" | wc -l)
# Check if there are any new test files
if [ "$file_count" -ne 0 ]; then
print_warning "Found $file_count new test files in \"$BRANCH_NAME\" 🎉."
fi

for file in $NEW_TEST_FILES; do
# if file is system test file run rake test:system filename
if [[ "$file" == *"./test/system/*_test.rb" ]]; then
print_warning "Running system test for \"$file\"..."
bundle exec rake test:system "$file"
else
print_warning "Running unit test on \"$file\"..."
bundle exec rake test "$file"
fi
# Capture the exit code from the test command to determine if it passed or failed
if [ $? -ne 0 ]; then
RAILS_TEST_EXIT_CODE=1
fi
done
WORK_DONE=1
elif [ -n "$CURRENT_TEST_FILES" ]; then
print_warning "No new tests found, running all Rails Tests ..."
make test
RAILS_TEST_EXIT_CODE=$?
WORK_DONE=1
else
print_error "No tests found in \"$BRANCH_NAME\". 🤨"
RAILS_TEST_EXIT_CODE=1
fi

if [ ! "$RAILS_TEST_EXIT_CODE" -eq 0 ]; then
git reset HEAD~
print_error "Cannot commit, tests are failing. Use --no-verify to force commit. 😖"
exit 1
fi

print_success "All tests are green, committing... 🎉"
exit 0
43 changes: 24 additions & 19 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,55 @@
# beware if you are in the habit of committing only partial modifications to a file:
# THIS HOOK WILL ADD ALL MODIFICATIONS TO A FILE TO THE COMMIT IF ANY FILE WAS CHANGED BY LINTING

list="issue spike task"
# Source common hook utilities
. "$(dirname "$0")/common.sh"

listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/"
# Initialize branch name
init_branch_name

BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //')
print_header "Checking \"$BRANCH_NAME\"..."

printf '\n\033[0;105mChecking "%s"... \033[0m\n', "$BRANCH_NAME"

if echo "$BRANCH_NAME" | grep -q '^(rebase)|(production)*$'; then
printf '\n\033[0;32mNo checks necessary on "%s", pushing now... 🎉\033[0m\n', "$BRANCH_NAME"
if should_skip_hook; then
print_success "No checks necessary on \"$BRANCH_NAME\", pushing now... 🎉"
exit 0
fi

# Identify staged Ruby-related files (including Gemfile/Rakefile) to lint before commit.
RUBY_FILES="$(git diff --diff-filter=d --name-only --cached | grep -E '(Gemfile|Rakefile|\.(rb|rake|ru))$')"

PRE_STATUS="$(git status | wc -l)"

# Initialise exit code variables to track success (0 = success)
RUBOCOP_EXIT_CODE=0
WORK_DONE=0

if [ -n "$RUBY_FILES" ]; then
printf '\nRunning Rubocop...'
for file in $RUBY_FILES; do
git show :"$file" | bundle exec rubocop -A --stdin "$file"
done
if [ -z "$RUBY_FILES" ]; then
print_error "There are currently no updated files in \"$BRANCH_NAME\". 🤨"
else
print_warning "Running Rubocop..."
# Convert space-separated file list into positional parameters for safe argument passing
set -- $RUBY_FILES
# Execute RuboCop with auto-fix enabled on the staged files that have been set
bundle exec rubocop -a --force-exclusion -- "$@"
# Capture the exit code from RuboCop command (0 = success, non-zero = errors)
RUBOCOP_EXIT_CODE=$?
# Flag that linting ran so we can report result and re-add files if needed.
WORK_DONE=1
else
RUBOCOP_EXIT_CODE=0
fi

POST_STATUS="$(git status | wc -l)"

if [ ! $RUBOCOP_EXIT_CODE -eq 0 ]; then
git reset HEAD
printf '\n\033[0;31mLinting has unfixable errors; please fix and restage your commit. 😖\033[0m\n'
print_error "Linting has uncorrectable errors; please fix and restage your commit. 😖"
exit 1
fi

if [ "$PRE_STATUS" != "$POST_STATUS" ]; then
git add "$RUBY_FILES" "$ESLINT_FILES" "$PRETTIER_FILES"
git add "$RUBY_FILES"
fi

if [ $WORK_DONE -eq 1 ]; then
printf '\n\033[0;32mLinting completed successfully! 🎉\033[0m\n'
if [ ! $WORK_DONE -eq 0 ]; then
print_success "Linting completed successfully! 🎉"
fi

exit 0
58 changes: 22 additions & 36 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -1,46 +1,32 @@
#!/bin/sh
#!/bin/bash
# Source common hook utilities
. "$(dirname "$0")/common.sh"

list="issue spike task"
# Initialize branch name
init_branch_name

listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/"
print_header "Checking \"$BRANCH_NAME\"..."

BRANCH_NAME=$(git branch --show-current | grep -E "$listRE" | sed 's/* //')

printf '\n\033[0;105mChecking "%s"... \033[0m\n', "$BRANCH_NAME"

if echo "$BRANCH_NAME" | grep -q '^(rebase)|(production)*$'; then
printf '\n\033[0;32mNo checks necessary on "%s", pushing now... 🎉\033[0m\n', "$BRANCH_NAME"
exit 0
fi

# Check for existence of "new or modified" test files
TEST_FILES="$(git diff --diff-filter=ACDM --name-only --cached | grep -E '(./test/*)$')"
# Get all test files to run tests
RUBY_FILES="$(git ls-files | grep -i -E '(_test\.rb)$')"

WORK_DONE=0

if [ -z "$TEST_FILES" ]; then
printf 'There are no new tests created in "%s".\n', "$BRANCH_NAME"
printf '\n\033[0;31mContinuing without new tests... 😖\033[0m\n'
# Skip on specific branches, with --no-verify flag, or when amending
if should_skip_hook; then
print_success "Skipping pre-push hook... 🎉"
exit 0
fi

if [ -n "$RUBY_FILES" ]; then
printf '\nRunning Unit Tests...'
make test
RUBY_TEST_EXIT_CODE=$?
WORK_DONE=1
# Check for existence of "new or modified" files
if ! git update-index -q --ignore-submodules --refresh; then
print_warning 'Up-to-date check failed 😖'
GEM_BUILD_EXIT_CODE=1
else
RUBY_TEST_EXIT_CODE=0
print_success 'Building Gem... '
make build
GEM_BUILD_EXIT_CODE=$?
fi

if [ ! $RUBY_TEST_EXIT_CODE -eq 0 ]; then
printf '\n\033[0;31mCannot push, tests are failing. Use --no-verify to force push. 😖\033[0m\n'
if [ $GEM_BUILD_EXIT_CODE -ne 0 ]; then
print_error 'Gem build failed. Please check your changes. 😖'
exit 1
else
print_success 'Gem build succeeded, pushing changes. 🎉'
exit 0
fi

if [ $WORK_DONE = 1 ]; then
printf '\n\033[0;32mAll tests are green, pushing... 🎉\033[0m\n'
fi

exit 0
Loading