Skip to content

Commit d70d175

Browse files
committed
🧰 Retemplate oauth with kettle-jem
1 parent af32336 commit d70d175

141 files changed

Lines changed: 4029 additions & 1686 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.config/mise/env.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# shellcheck shell=bash
2+
3+
prepend_unique_path_value() {
4+
local value="$1"
5+
local current="$2"
6+
7+
if [[ -z "$current" ]]; then
8+
printf '%s' "$value"
9+
elif [[ ":$current:" == *":$value:"* ]]; then
10+
printf '%s' "$current"
11+
else
12+
printf '%s:%s' "$value" "$current"
13+
fi
14+
}
15+
16+
# Preserve existing values while prepending the project defaults needed by TreeHaver.
17+
_tree_sitter_runtime_lib="${TREE_SITTER_RUNTIME_LIB:-/home/linuxbrew/.linuxbrew/Cellar/tree-sitter/0.26.6/lib/libtree-sitter.so}"
18+
_tree_sitter_runtime_dir="$(dirname "${_tree_sitter_runtime_lib}")"
19+
_tree_sitter_java_jars_dir="${TREE_SITTER_JAVA_JARS_DIR:-}"
20+
21+
if [[ -n "${_tree_sitter_java_jars_dir}" ]]; then
22+
_tree_sitter_java_jar="${_tree_sitter_java_jars_dir}/jtreesitter-0.26.0.jar"
23+
export CLASSPATH="$(prepend_unique_path_value "${_tree_sitter_java_jar}" "${CLASSPATH:-}")"
24+
fi
25+
26+
export LD_LIBRARY_PATH="$(prepend_unique_path_value "${_tree_sitter_runtime_dir}" "${LD_LIBRARY_PATH:-}")"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "Apt Install Packages",
3+
"id": "apt-install",
4+
"version": "1.0.0",
5+
"description": "More packages are needed",
6+
"install": {
7+
"script": "install.sh"
8+
}
9+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/sh
2+
set -e # Exit on error
3+
4+
# Install basic development dependencies for Ruby & JRuby projects
5+
apt-get update -y
6+
apt-get install -y direnv default-jdk git zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev
7+
8+
# Support for PostgreSQL (commented out by default)
9+
# apt-get install -y postgresql libpq-dev
10+
11+
# NOTE: Tree-sitter setup is NOT done here because the workspace is not mounted yet
12+
# during the devcontainer build phase. Tree-sitter setup happens in postCreateCommand
13+
# after the workspace is mounted. See devcontainer.json for details.
14+
# This gem needs ALL grammars for top-level merging tool (handled by setup-tree-sitter.sh).
15+
16+
echo "Basic apt packages installed. Tree-sitter will be set up after workspace mount."
17+
18+
# Adds the direnv setup script to ~/.bashrc file (at the end)
19+
echo 'eval "$(direnv hook bash)"' >> ~/.bashrc

.devcontainer/devcontainer.json

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
22
// README at: https://github.com/devcontainers/templates/tree/main/src/ruby
33
{
4-
"name": "Ruby",
4+
"name": "Ruby",
55
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6-
"image": "mcr.microsoft.com/devcontainers/ruby:1-3-bookworm",
6+
"image": "mcr.microsoft.com/devcontainers/ruby:1-3-bookworm",
7+
// Features to add to the dev container. More info: https://containers.dev/features.
8+
"features": {
9+
"./apt-install": {}
10+
},
11+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
12+
// "forwardPorts": [],
13+
14+
// Use 'postCreateCommand' to run commands after the container is created.
15+
// First setup tree-sitter (auto-detects sudo requirement), then run bundle as the regular user
16+
// Use ${containerWorkspaceFolder} to get the actual workspace path in the container
17+
"postCreateCommand": "bash ${containerWorkspaceFolder}/.devcontainer/scripts/setup-tree-sitter.sh --workspace=${containerWorkspaceFolder} && bundle update --bundler",
718

819
// Features to add to the dev container. More info: https://containers.dev/features.
920
// "features": {},
@@ -15,11 +26,11 @@
1526
// "postCreateCommand": "ruby --version",
1627

1728
// Configure tool-specific properties.
18-
"customizations" : {
19-
"jetbrains" : {
20-
"backend" : "RubyMine"
29+
"customizations": {
30+
"jetbrains": {
31+
"backend": "RubyMine"
2132
}
22-
},
33+
}
2334

2435
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
2536
// "remoteUser": "root"
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Setup script for tree-sitter dependencies (Ubuntu/Debian)
5+
# Works for both GitHub Actions and devcontainer environments
6+
#
7+
# Dual-Environment Design:
8+
# - GitHub Actions: Runs as non-root user, auto-detects need for sudo
9+
# - Devcontainer: Can run as root (apt-install feature) or non-root (postCreateCommand)
10+
# - Auto-detection: Checks if running as root (id -u = 0), uses sudo if non-root
11+
#
12+
# Grammar building is delegated to tsdl (https://github.com/stackmystack/tsdl).
13+
# Configure grammars and versions in parsers.toml at the project root.
14+
#
15+
# Options:
16+
# --sudo: Force use of sudo (optional, auto-detected by default)
17+
# --cli: Install tree-sitter-cli via npm (optional)
18+
# --build: Build and install the tree-sitter C runtime from source when distro packages are missing (optional)
19+
# --tsdl-version VERSION: Pin tsdl release version (default: v2.0.0)
20+
# --workspace PATH: Workspace root path for informational/debugging purposes only
21+
22+
SUDO=""
23+
INSTALL_CLI=false
24+
BUILD_FROM_SOURCE=false
25+
TSDL_VERSION="v2.0.0"
26+
WORKSPACE_ROOT="/workspaces/${PWD##*/}"
27+
28+
while [[ $# -gt 0 ]]; do
29+
case $1 in
30+
--sudo) SUDO="sudo"; shift ;;
31+
--cli) INSTALL_CLI=true; shift ;;
32+
--build) BUILD_FROM_SOURCE=true; shift ;;
33+
--tsdl-version) TSDL_VERSION="$2"; shift 2 ;;
34+
--tsdl-version=*) TSDL_VERSION="${1#*=}"; shift ;;
35+
--workspace) WORKSPACE_ROOT="$2"; shift 2 ;;
36+
--workspace=*) WORKSPACE_ROOT="${1#*=}"; shift ;;
37+
*) echo "Unknown option: $1" >&2; shift ;;
38+
esac
39+
done
40+
41+
# Auto-detect if we need sudo (running as non-root)
42+
if [ -z "$SUDO" ] && [ "$(id -u)" -ne 0 ]; then
43+
SUDO="sudo"
44+
fi
45+
46+
echo "Configuration:"
47+
echo " Workspace root: $WORKSPACE_ROOT (informational only)"
48+
echo " Using sudo: $([ -n "$SUDO" ] && echo "yes" || echo "no")"
49+
echo " Install CLI: $INSTALL_CLI"
50+
echo " Build from source: $BUILD_FROM_SOURCE"
51+
echo " tsdl version: $TSDL_VERSION"
52+
echo ""
53+
54+
have_cmd() { command -v "$1" >/dev/null 2>&1; }
55+
56+
have_tree_sitter() {
57+
[ -f /usr/include/tree-sitter/api.h ] && return 0
58+
[ -f /usr/local/include/tree-sitter/api.h ] && return 0
59+
[ -f /usr/local/include/tree-sitter/lib/include/api.h ] && return 0
60+
ldconfig -p 2>/dev/null | grep -q libtree-sitter && return 0 || return 1
61+
}
62+
63+
install_tree_sitter_from_source() {
64+
echo "[tree-sitter] Building runtime from source..."
65+
tmpdir=$(mktemp -d /tmp/tree-sitter-src-XXXX)
66+
trap 'rm -rf "$tmpdir"' EXIT
67+
git clone --depth 1 https://github.com/tree-sitter/tree-sitter.git "$tmpdir" || return 1
68+
pushd "$tmpdir" >/dev/null || return 1
69+
if ! make; then
70+
echo "[tree-sitter] ERROR: 'make' failed" >&2
71+
popd >/dev/null
72+
return 1
73+
fi
74+
$SUDO mkdir -p /usr/local/include/tree-sitter
75+
$SUDO cp -r lib/include/* /usr/local/include/tree-sitter/ || true
76+
$SUDO cp -a lib/libtree-sitter.* /usr/local/lib/ 2>/dev/null || true
77+
have_cmd ldconfig && $SUDO ldconfig || true
78+
popd >/dev/null
79+
echo "[tree-sitter] Runtime installed to /usr/local."
80+
return 0
81+
}
82+
83+
install_tsdl() {
84+
if have_cmd tsdl; then
85+
echo "[tsdl] Already installed: $(tsdl --version)"
86+
return 0
87+
fi
88+
89+
echo "[tsdl] Installing tsdl ${TSDL_VERSION}..."
90+
local arch
91+
arch="$(uname -m)"
92+
case "$arch" in
93+
x86_64) arch="x64" ;;
94+
aarch64) arch="arm64" ;;
95+
armv7l) arch="arm" ;;
96+
i686) arch="x86" ;;
97+
*) echo "[tsdl] ERROR: Unsupported architecture: $arch" >&2; return 1 ;;
98+
esac
99+
100+
local os
101+
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
102+
case "$os" in
103+
linux) os="linux" ;;
104+
darwin) os="macos" ;;
105+
*) echo "[tsdl] ERROR: Unsupported OS: $os" >&2; return 1 ;;
106+
esac
107+
108+
local url="https://github.com/stackmystack/tsdl/releases/download/${TSDL_VERSION}/tsdl-${os}-${arch}.gz"
109+
local tmpbin
110+
tmpbin=$(mktemp /tmp/tsdl-XXXX)
111+
112+
if ! wget -q "$url" -O "${tmpbin}.gz"; then
113+
echo "[tsdl] ERROR: Failed to download from $url" >&2
114+
return 1
115+
fi
116+
gunzip -f "${tmpbin}.gz"
117+
chmod +x "$tmpbin"
118+
$SUDO mv "$tmpbin" /usr/local/bin/tsdl
119+
echo "[tsdl] Installed: $(tsdl --version)"
120+
}
121+
122+
# --- 1. System dependencies ---
123+
echo "Installing system dependencies..."
124+
$SUDO apt-get update -y
125+
if ! $SUDO apt-get install -y \
126+
build-essential \
127+
pkg-config \
128+
$( [ "$BUILD_FROM_SOURCE" = false ] && echo "libtree-sitter-dev" ) \
129+
wget \
130+
gcc \
131+
g++ \
132+
make \
133+
zlib1g-dev \
134+
libssl-dev \
135+
libreadline-dev \
136+
libyaml-dev \
137+
libxml2-dev \
138+
libxslt1-dev \
139+
libcurl4-openssl-dev \
140+
software-properties-common \
141+
libffi-dev; then
142+
echo "ERROR: apt-get failed to install required packages." >&2
143+
exit 1
144+
fi
145+
146+
# --- 2. Tree-sitter runtime ---
147+
if [ "$BUILD_FROM_SOURCE" = true ]; then
148+
echo "[tree-sitter] --build specified; building runtime from source."
149+
fi
150+
151+
if ! have_tree_sitter; then
152+
if [ "$BUILD_FROM_SOURCE" = true ]; then
153+
if ! install_tree_sitter_from_source; then
154+
echo "[tree-sitter] ERROR: Failed to build runtime. Aborting." >&2
155+
exit 1
156+
fi
157+
else
158+
echo "[tree-sitter] ERROR: Runtime (headers/libs) not found." >&2
159+
echo "Install libtree-sitter-dev or re-run with --build." >&2
160+
exit 1
161+
fi
162+
fi
163+
164+
# --- 3. tree-sitter-cli (optional) ---
165+
if [ "$INSTALL_CLI" = true ]; then
166+
echo "Installing tree-sitter-cli via npm..."
167+
$SUDO npm install -g tree-sitter-cli
168+
else
169+
echo "Skipping tree-sitter-cli (use --cli to install)"
170+
fi
171+
172+
# --- 4. Install tsdl and build grammars ---
173+
install_tsdl
174+
175+
echo ""
176+
echo "Building tree-sitter grammars via tsdl..."
177+
# Use parsers.toml from the project root if it exists, otherwise build defaults.
178+
# tsdl automatically reads parsers.toml in the current directory.
179+
if [ -f parsers.toml ]; then
180+
echo "[tsdl] Using parsers.toml config"
181+
$SUDO tsdl build --out-dir /usr/local/lib --progress plain
182+
else
183+
echo "[tsdl] No parsers.toml found; building default grammars: toml json bash rbs"
184+
$SUDO tsdl build toml json bash rbs --out-dir /usr/local/lib --progress plain
185+
fi
186+
187+
$SUDO ldconfig || echo "WARNING: ldconfig failed" >&2
188+
189+
echo ""
190+
echo "tree-sitter setup complete!"
191+
echo ""
192+
echo "Detected library paths:"
193+
194+
if [ -f /usr/lib/x86_64-linux-gnu/libtree-sitter.so.0 ]; then
195+
echo " TREE_SITTER_RUNTIME_LIB=/usr/lib/x86_64-linux-gnu/libtree-sitter.so.0"
196+
elif [ -f /usr/lib/x86_64-linux-gnu/libtree-sitter.so ]; then
197+
echo " TREE_SITTER_RUNTIME_LIB=/usr/lib/x86_64-linux-gnu/libtree-sitter.so"
198+
elif [ -f /usr/lib/libtree-sitter.so.0 ]; then
199+
echo " TREE_SITTER_RUNTIME_LIB=/usr/lib/libtree-sitter.so.0"
200+
elif [ -f /usr/lib/libtree-sitter.so ]; then
201+
echo " TREE_SITTER_RUNTIME_LIB=/usr/lib/libtree-sitter.so"
202+
else
203+
echo " WARNING: Could not find libtree-sitter runtime library!"
204+
fi
205+
206+
echo ""
207+
echo "Grammar libraries:"
208+
for lib in /usr/local/lib/libtree-sitter-*.so; do
209+
[ -f "$lib" ] && echo " $lib"
210+
done

.gemrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
gem: --no-document

.git-hooks/commit-msg

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
#!/usr/bin/env ruby
22
# vim: set syntax=ruby
33

4+
# kettle-jem:freeze
5+
# To retain chunks of comments & code during kettle-jem templating:
6+
# Wrap custom sections with freeze markers (e.g., as above and below this comment chunk).
7+
# kettle-jem will then preserve content between those markers across template runs.
8+
# kettle-jem:unfreeze
9+
410
# Do not rely on Bundler; allow running outside a Bundler context
511
begin
612
require "rubygems"
@@ -20,24 +26,24 @@ begin
2026
else
2127
denied = <<~EOM
2228
Oh snap, think again...
23-
29+
2430
______ _______ ___ _______ _______ _______ _______ ______ __
2531
| _ | | | | || || || || || | | |
2632
| | || | ___| | || ___|| ||_ _|| ___|| _ || |
2733
| |_||_ | |___ | || |___ | | | | | |___ | | | || |
2834
| __ || ___| ___| || ___|| _| | | | ___|| |_| ||__|
2935
| | | || |___ | || |___ | |_ | | | |___ | | __
3036
|___| |_||_______||_______||_______||_______| |___| |_______||______| |__|
31-
32-
37+
38+
3339
Did you forget to add a relevant gitmoji? (see https://gitmoji.dev/ for tools)
3440
In this project, a Gitmoji must be the first grapheme of the commit message.
3541
What's a grapheme?
3642
A symbol rendered to be visually identifiable as a single character, but which may be composed of multiple Unicode code points)
3743
Must match: #{Gitmoji::Regex::REGEX}
3844
#{"Found a gitmoji at character index #{gitmoji_index}... not good enough.\n" if gitmoji_index}
3945
Example: git commit -m "✨ My excellent new feature"
40-
46+
4147
EOM
4248
puts denied
4349
exit(1)
@@ -47,7 +53,7 @@ rescue LoadError => e
4753
gitmoji-regex gem not found: #{e.class}: #{e.message}.
4854
Skipping gitmoji check and allowing commit to proceed.
4955
Recommendation: add 'gitmoji-regex' to your development dependencies to enable this check.
50-
56+
5157
EOM
5258
warn(failure)
5359
exit(0)

.git-hooks/prepare-commit-msg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Fail on error and unset variables
44
set -eu
55

6+
# Run the generated wrapper directly so hook execution does not depend on shell activation.
67
# We are not using direnv exec here because mise and direnv can result in conflicting PATH settings:
78
# See: https://mise.jdx.dev/direnv.html
89
exec "kettle-commit-msg" "$@"

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# <<structuredmerge:git-drivers>> do not edit below this line
2+
*.rb diff=smorg-ruby
3+
# <</structuredmerge:git-drivers>>

.github/.codecov.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
codecov:
2+
bot: "autobolt"
3+
max_report_age: 24
4+
disable_default_path_fixes: no
5+
require_ci_to_pass: yes
6+
notify:
7+
after_n_builds: 2
8+
wait_for_ci: yes
9+
coverage:
10+
status:
11+
project:
12+
default:
13+
target: 100%
14+
threshold: 1%

0 commit comments

Comments
 (0)