diff --git a/.devcontainer/setup-git.sh b/.devcontainer/setup-git.sh index 34b3ce3..838242f 100755 --- a/.devcontainer/setup-git.sh +++ b/.devcontainer/setup-git.sh @@ -51,15 +51,15 @@ if grep -q '^\[alias\]' ~/.gitconfig.host; then # First, collect all aliases from host config TEMP_ALIASES=$(mktemp) - sed -n '/^\[alias\]/,/^\[/p' ~/.gitconfig.host | \ - grep -v '^\[' | \ - grep -v '^$' | \ + sed -n '/^\[alias\]/,/^\[/p' ~/.gitconfig.host | + grep -v '^\[' | + grep -v '^$' | while IFS= read -r line; do # Skip aliases with macOS-specific paths if echo "$line" | grep -q -E '/(Applications|usr/local)'; then continue fi - echo "$line" >> "$TEMP_ALIASES" + echo "$line" >>"$TEMP_ALIASES" done # Apply each alias (git config --global overwrites existing values = idempotent) @@ -68,8 +68,8 @@ if grep -q '^\[alias\]' ~/.gitconfig.host; then ALIAS_NAME=$(echo "$line" | awk '{print $1}') ALIAS_VALUE=$(echo "$line" | sed "s/^$ALIAS_NAME = //") git config --global "alias.$ALIAS_NAME" "$ALIAS_VALUE" 2>/dev/null || true - done < "$TEMP_ALIASES" - echo " Synced $(wc -l < "$TEMP_ALIASES") aliases" + done <"$TEMP_ALIASES" + echo " Synced $(wc -l <"$TEMP_ALIASES") aliases" fi rm -f "$TEMP_ALIASES" diff --git a/scripts/develop b/scripts/develop index b19d3bf..fe5fe7d 100755 --- a/scripts/develop +++ b/scripts/develop @@ -31,8 +31,8 @@ fi # Create config dir if not present if [[ ! -d ${PWD}/config ]]; then - mkdir -p "${PWD}/config" - hass --config "${PWD}/config" --script ensure_config + mkdir -p "${PWD}/config" + hass --config "${PWD}/config" --script ensure_config fi "$SCRIPT_DIR/setup/sync-hacs" diff --git a/scripts/docs/build-changed-sites b/scripts/docs/build-changed-sites index 4c473e2..de77a00 100644 --- a/scripts/docs/build-changed-sites +++ b/scripts/docs/build-changed-sites @@ -11,12 +11,12 @@ build_developer=false for file in "$@"; do case "$file" in - docs/user/*) - build_user=true - ;; - docs/developer/*) - build_developer=true - ;; + docs/user/*) + build_user=true + ;; + docs/developer/*) + build_developer=true + ;; esac done diff --git a/scripts/release/generate-notes b/scripts/release/generate-notes index 11710f3..141347a 100755 --- a/scripts/release/generate-notes +++ b/scripts/release/generate-notes @@ -66,12 +66,12 @@ USER_FACING_PATHS=( # Parse common truthy values from environment variables is_truthy() { case "${1,,}" in - 1 | true | yes | on) - return 0 - ;; - *) - return 1 - ;; + 1 | true | yes | on) + return 0 + ;; + *) + return 1 + ;; esac } @@ -168,8 +168,8 @@ build_diff_context() { if ! diff_context=$( set -o pipefail git diff --unified=0 --no-color --minimal --patience --diff-filter=AM \ - "${FROM_TAG}..${TO_TAG}" -- "${USER_FACING_PATHS[@]}" 2>/dev/null \ - | awk ' + "${FROM_TAG}..${TO_TAG}" -- "${USER_FACING_PATHS[@]}" 2>/dev/null | + awk ' /^diff --git / { print; next } /^--- / || /^\+\+\+ / || /^@@ / { print; next } /^[+-]/ { @@ -177,18 +177,18 @@ build_diff_context() { print next } - ' \ - | head -c "$RELEASE_NOTES_DIFF_MAX_BYTES" + ' | + head -c "$RELEASE_NOTES_DIFF_MAX_BYTES" ); then log_info "${YELLOW}Warning: compact diff generation failed, falling back to legacy diff context${NC}" diff_context=$(git diff --unified=2 --diff-filter=AM \ - "${FROM_TAG}..${TO_TAG}" -- "${USER_FACING_PATHS[@]}" 2>/dev/null \ - | head -c "$RELEASE_NOTES_DIFF_MAX_BYTES" || true) + "${FROM_TAG}..${TO_TAG}" -- "${USER_FACING_PATHS[@]}" 2>/dev/null | + head -c "$RELEASE_NOTES_DIFF_MAX_BYTES" || true) fi else diff_context=$(git diff --unified=2 --diff-filter=AM \ - "${FROM_TAG}..${TO_TAG}" -- "${USER_FACING_PATHS[@]}" 2>/dev/null \ - | head -c "$RELEASE_NOTES_DIFF_MAX_BYTES" || true) + "${FROM_TAG}..${TO_TAG}" -- "${USER_FACING_PATHS[@]}" 2>/dev/null | + head -c "$RELEASE_NOTES_DIFF_MAX_BYTES" || true) fi echo "$diff_context" @@ -264,8 +264,8 @@ generate_with_copilot() { FINAL_FILE_CHANGES=$(git diff --name-status "${FROM_TAG}..${TO_TAG}" 2>/dev/null || true) # Revert commits are useful chronology hints (earlier changes may be superseded). - REVERT_COMMITS=$(git log --reverse --pretty=format:"%h | %s" "${FROM_TAG}..${TO_TAG}" \ - | grep -Ei '\|[[:space:]]*revert\b' || true) + REVERT_COMMITS=$(git log --reverse --pretty=format:"%h | %s" "${FROM_TAG}..${TO_TAG}" | + grep -Ei '\|[[:space:]]*revert\b' || true) if [[ -z $FINAL_FILE_CHANGES ]]; then FINAL_FILE_CHANGES="(none)" @@ -442,7 +442,7 @@ End after the Buy Me A Coffee button. No meta-commentary, no explanations." # Save prompt to temp file for copilot TEMP_PROMPT=$(mktemp) - echo "$PROMPT" > "$TEMP_PROMPT" + echo "$PROMPT" >"$TEMP_PROMPT" # Use Claude Sonnet for better user-focused, plain-language release notes. # Haiku tends to echo technical commit language; Sonnet better translates to user benefits. @@ -450,7 +450,7 @@ End after the Buy Me A Coffee button. No meta-commentary, no explanations." COPILOT_MODEL="${COPILOT_MODEL:-claude-sonnet-4.6}" # Call copilot CLI (it will handle authentication interactively) - copilot --model "$COPILOT_MODEL" < "$TEMP_PROMPT" || { + copilot --model "$COPILOT_MODEL" <"$TEMP_PROMPT" || { echo "" log_info "${YELLOW}Warning: GitHub Copilot CLI failed or was not authenticated${NC}" log_info "${YELLOW}Falling back to git-cliff${NC}" @@ -501,7 +501,7 @@ generate_with_gitcliff() { # Create temporary cliff.toml if not exists if [ ! -f "cliff.toml" ]; then - cat > /tmp/cliff.toml <<'EOF' + cat >/tmp/cliff.toml <<'EOF' [changelog] header = "" body = """ @@ -628,7 +628,7 @@ EOF ') printf "%s\n" "$CLIFF_OUTPUT" - echo "" # Ensure output ends with newline (cliff.toml trim=true removes trailing newline) + echo "" # Ensure output ends with newline (cliff.toml trim=true removes trailing newline) if [ "$CLIFF_CONFIG" = "/tmp/cliff.toml" ]; then rm -f /tmp/cliff.toml @@ -722,22 +722,20 @@ generate_with_manual() { # Append to appropriate file case "$TYPE" in - whats_new) - echo "$LINE" >> "$WHATS_NEW_FILE" - ;; - fixed) - echo "$LINE" >> "$FIXED_FILE" - ;; - reliable) - echo "$LINE" >> "$RELIABLE_FILE" - ;; - deps) - echo "$LINE" >> "$DEPS_FILE" - ;; - skip) - ;; - *) - ;; + whats_new) + echo "$LINE" >>"$WHATS_NEW_FILE" + ;; + fixed) + echo "$LINE" >>"$FIXED_FILE" + ;; + reliable) + echo "$LINE" >>"$RELIABLE_FILE" + ;; + deps) + echo "$LINE" >>"$DEPS_FILE" + ;; + skip) ;; + *) ;; esac done @@ -797,49 +795,49 @@ fi # Validate backend availability case "$BACKEND" in - copilot) - if ! command -v copilot >/dev/null 2>&1; then - echo -e "${RED}Error: GitHub Copilot CLI not found${NC}" >&2 - echo "Install: npm install -g @github/copilot" >&2 - echo "See: https://github.com/github/copilot-cli" >&2 - exit 1 - fi - ;; - git-cliff) - if ! command -v git-cliff >/dev/null 2>&1; then - echo -e "${RED}Error: git-cliff not found${NC}" >&2 - echo "Install: https://git-cliff.org/docs/installation" >&2 - exit 1 - fi - ;; +copilot) + if ! command -v copilot >/dev/null 2>&1; then + echo -e "${RED}Error: GitHub Copilot CLI not found${NC}" >&2 + echo "Install: npm install -g @github/copilot" >&2 + echo "See: https://github.com/github/copilot-cli" >&2 + exit 1 + fi + ;; +git-cliff) + if ! command -v git-cliff >/dev/null 2>&1; then + echo -e "${RED}Error: git-cliff not found${NC}" >&2 + echo "Install: https://git-cliff.org/docs/installation" >&2 + exit 1 + fi + ;; esac # Generate to temp file if auto-update is possible, else stdout if [ "$AUTO_UPDATE_AVAILABLE" = "true" ]; then TEMP_NOTES=$(mktemp) case "$BACKEND" in - copilot) - generate_with_copilot > "$TEMP_NOTES" - ;; - git-cliff) - generate_with_gitcliff > "$TEMP_NOTES" - ;; - manual) - generate_with_manual > "$TEMP_NOTES" - ;; + copilot) + generate_with_copilot >"$TEMP_NOTES" + ;; + git-cliff) + generate_with_gitcliff >"$TEMP_NOTES" + ;; + manual) + generate_with_manual >"$TEMP_NOTES" + ;; esac else # No auto-update, just output to stdout case "$BACKEND" in - copilot) - generate_with_copilot - ;; - git-cliff) - generate_with_gitcliff - ;; - manual) - generate_with_manual - ;; + copilot) + generate_with_copilot + ;; + git-cliff) + generate_with_gitcliff + ;; + manual) + generate_with_manual + ;; esac echo "" >&2 @@ -903,7 +901,7 @@ fi # Save body (without H1 title) to temp file for GitHub TEMP_BODY=$(mktemp) -echo "$NOTES_BODY" > "$TEMP_BODY" +echo "$NOTES_BODY" >"$TEMP_BODY" # Show the generated notes (with title for preview) if [ -n "$EXTRACTED_TITLE" ]; then diff --git a/scripts/release/hassfest b/scripts/release/hassfest index e8fb935..7dd6deb 100755 --- a/scripts/release/hassfest +++ b/scripts/release/hassfest @@ -37,7 +37,7 @@ fi # Check 2: manifest.json syntax printf "%b Checking manifest.json syntax...%b\n" "$BOLD" "$NC" -if ! python -m json.tool "$INTEGRATION_PATH/manifest.json" > /dev/null 2>&1; then +if ! python -m json.tool "$INTEGRATION_PATH/manifest.json" >/dev/null 2>&1; then log_result 1 "manifest.json has invalid JSON syntax" ERRORS=$((ERRORS + 1)) else @@ -49,7 +49,7 @@ printf "%b Checking translation files syntax...%b\n" "$BOLD" "$NC" for lang_file in "$INTEGRATION_PATH"/translations/*.json; do if [[ -f $lang_file ]]; then lang=$(basename "$lang_file") - if ! python -m json.tool "$lang_file" > /dev/null 2>&1; then + if ! python -m json.tool "$lang_file" >/dev/null 2>&1; then log_result 1 "$lang has invalid JSON syntax" ERRORS=$((ERRORS + 1)) else @@ -64,7 +64,7 @@ if [[ -d $INTEGRATION_PATH/custom_translations ]]; then for lang_file in "$INTEGRATION_PATH"/custom_translations/*.json; do if [[ -f $lang_file ]]; then lang=$(basename "$lang_file") - if ! python -m json.tool "$lang_file" > /dev/null 2>&1; then + if ! python -m json.tool "$lang_file" >/dev/null 2>&1; then log_result 1 "custom_translations/$lang has invalid JSON syntax" ERRORS=$((ERRORS + 1)) else diff --git a/scripts/release/prepare b/scripts/release/prepare index 37303bd..eb39190 100755 --- a/scripts/release/prepare +++ b/scripts/release/prepare @@ -94,7 +94,7 @@ require_command "jq" "apt-get install jq (or brew install jq)" cp "$MANIFEST" "$MANIFEST.backup" # Update version with jq -if ! jq ".version = \"$VERSION\"" "$MANIFEST" > "$MANIFEST.tmp"; then +if ! jq ".version = \"$VERSION\"" "$MANIFEST" >"$MANIFEST.tmp"; then mv "$MANIFEST.backup" "$MANIFEST" die "Failed to update manifest.json" fi diff --git a/scripts/release/suggest-version b/scripts/release/suggest-version index d0774c2..0ff9669 100755 --- a/scripts/release/suggest-version +++ b/scripts/release/suggest-version @@ -66,7 +66,7 @@ parse_version() { } CURRENT_VERSION="${FROM_TAG#v}" -read -r MAJOR MINOR PATCH PRERELEASE <<< "$(parse_version "$CURRENT_VERSION")" +read -r MAJOR MINOR PATCH PRERELEASE <<<"$(parse_version "$CURRENT_VERSION")" printf "Current released version: %bv%s.%s.%s%s%b\n" "$BOLD" "$MAJOR" "$MINOR" "$PATCH" "$PRERELEASE" "$NC" if [[ $MANIFEST_VERSION != "$CURRENT_VERSION" ]]; then diff --git a/scripts/setup/bootstrap b/scripts/setup/bootstrap index 9bf072b..3042e8e 100755 --- a/scripts/setup/bootstrap +++ b/scripts/setup/bootstrap @@ -26,14 +26,14 @@ sudo apt-get upgrade -y # Ensure curl is available (needed to fetch Home Assistant requirement files) if ! command -v curl >/dev/null 2>&1; then - log_header "Installing curl" - sudo apt-get install -y curl + log_header "Installing curl" + sudo apt-get install -y curl fi log_header "Checking for uv" if ! command -v uv >/dev/null 2>&1; then - log_info "UV not found, installing..." - pipx install uv + log_info "UV not found, installing..." + pipx install uv fi # if no venv, create one @@ -64,20 +64,20 @@ mkdir -p "${HA_TMP_DIR}/homeassistant" log_step "Downloading package_constraints.txt..." curl -fsSL "${HA_CORE_BASE_URL}/homeassistant/package_constraints.txt" \ - -o "${HA_TMP_DIR}/homeassistant/package_constraints.txt" + -o "${HA_TMP_DIR}/homeassistant/package_constraints.txt" log_step "Downloading core requirements.txt..." curl -fsSL "${HA_CORE_BASE_URL}/requirements.txt" \ - -o "${HA_TMP_DIR}/requirements.txt" + -o "${HA_TMP_DIR}/requirements.txt" # Optional: download requirements_all.txt for all integrations (large file) log_step "Downloading requirements_all.txt (optional)..." if curl -fsSL "${HA_CORE_BASE_URL}/requirements_all.txt" \ - -o "${HA_TMP_DIR}/requirements_all.txt"; then - HAVE_REQ_ALL=1 + -o "${HA_TMP_DIR}/requirements_all.txt"; then + HAVE_REQ_ALL=1 else - log_info "(requirements_all.txt not found for ${HA_VERSION}, skipping)" - HAVE_REQ_ALL=0 + log_info "(requirements_all.txt not found for ${HA_VERSION}, skipping)" + HAVE_REQ_ALL=0 fi log_header "Installing Home Assistant package" @@ -85,15 +85,15 @@ uv pip install "homeassistant==${HA_VERSION}" echo "==> Installing Home Assistant voice/intent dependencies (hassil, home-assistant-intents)..." uv pip install \ - --constraint "${HA_TMP_DIR}/homeassistant/package_constraints.txt" \ - hassil \ - home-assistant-intents || echo " (Optional deps failed, continuing...)" + --constraint "${HA_TMP_DIR}/homeassistant/package_constraints.txt" \ + hassil \ + home-assistant-intents || echo " (Optional deps failed, continuing...)" if [[ $HAVE_REQ_ALL -eq 1 ]]; then - echo "==> Installing Home Assistant integration dependencies (requirements_all.txt)..." - uv pip install \ - --constraint "${HA_TMP_DIR}/homeassistant/package_constraints.txt" \ - --requirement "${HA_TMP_DIR}/requirements_all.txt" + echo "==> Installing Home Assistant integration dependencies (requirements_all.txt)..." + uv pip install \ + --constraint "${HA_TMP_DIR}/homeassistant/package_constraints.txt" \ + --requirement "${HA_TMP_DIR}/requirements_all.txt" fi echo "==> Installing pre-commit hooks..." @@ -101,11 +101,11 @@ pre-commit install log_header "Updating shell environment" if ! grep -q "source $HOME/.venv/bin/activate" "$HOME/.bashrc" 2>/dev/null; then - echo "source $HOME/.venv/bin/activate" >> "$HOME/.bashrc" + echo "source $HOME/.venv/bin/activate" >>"$HOME/.bashrc" fi if [[ -f $HOME/.zshrc ]]; then if ! grep -q "source $HOME/.venv/bin/activate" "$HOME/.zshrc"; then - echo "source $HOME/.venv/bin/activate" >> "$HOME/.zshrc" + echo "source $HOME/.venv/bin/activate" >>"$HOME/.zshrc" fi fi diff --git a/scripts/setup/setup b/scripts/setup/setup index c1b82d3..baa1cd7 100755 --- a/scripts/setup/setup +++ b/scripts/setup/setup @@ -74,7 +74,7 @@ ensure_command_alias "rg" "ripgrep" # Ensure user-local bin directory is available in interactive shells. if ! grep -q '\$HOME/.local/bin' "$HOME/.zshrc" 2>/dev/null; then - printf '\n# Added by scripts/setup/setup\nexport PATH="$HOME/.local/bin:$PATH"\n' >> "$HOME/.zshrc" + printf '\n# Added by scripts/setup/setup\nexport PATH="$HOME/.local/bin:$PATH"\n' >>"$HOME/.zshrc" fi # Install HACS for testing with other custom components @@ -104,9 +104,9 @@ fi # Download and extract HACS (stable release ZIP) cd config/custom_components log_step "Downloading HACS" -if wget -q https://github.com/hacs/integration/releases/latest/download/hacs.zip && \ - unzip -q hacs.zip -d hacs && \ - rm hacs.zip; then +if wget -q https://github.com/hacs/integration/releases/latest/download/hacs.zip && + unzip -q hacs.zip -d hacs && + rm hacs.zip; then cd ../.. # Install HACS Python dependencies