[llvm] [libcxx] Add pre-commit hooks and git config for libc++ & git-clang-format. (PR #73798)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 29 08:00:03 PST 2023


https://github.com/EricWF updated https://github.com/llvm/llvm-project/pull/73798

>From e02dd1680546fa5f9ad70446f9a9a5b3eb431f5b Mon Sep 17 00:00:00 2001
From: eric <eric at efcs.ca>
Date: Wed, 29 Nov 2023 09:38:13 -0500
Subject: [PATCH 1/3] Add pre-commit hooks and git config for libc++ &
 git-clang-format.

This patch aims to ease the entry into libc++'s codebase by

(A) Setting up the users clangFormat.extensions values in the
.git/config. libc++ needs this to format extensionless files.

(2) Install a pre-commit hook which checks for files which are
   misformatted and offers to format them.

These can be installed by running
./libcxx/utils/formatting/setup-formatting-config.sh

Documentation is incoming
---
 .../libcxx-pre-commit-formatting-hook.sh      | 31 ++++++++
 .../formatting/setup-formatting-config.sh     | 75 +++++++++++++++++++
 2 files changed, 106 insertions(+)
 create mode 100755 libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh
 create mode 100755 libcxx/utils/formatting/setup-formatting-config.sh

diff --git a/libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh b/libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh
new file mode 100755
index 000000000000000..741b686e5e5a402
--- /dev/null
+++ b/libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+
+# Define the staged files
+staged_files=$(git diff --cached --name-only --diff-filter=d -- libcxx/ libcxxabi/ libunwind/)
+
+# Check if any of the staged files have not been properly formatted with git-clang-format
+
+echo "Checking $file..."
+formatting_diff=$(git-clang-format --diff -- "$staged_files") # quotes are used here
+if [[ "$formatting_diff" != "no modified files to format" && "$formatting_diff" != "clang-format did not modify any files" ]]; then
+    echo "$file has not been formatted with git-clang-format."
+    git-clang-format --diff -- "$staged_files"
+    read -p "Format the files [Y/n]? " -n 1 -r
+      echo
+    if [[ $REPLY =~ ^[Yy]$ ]]
+      then
+          git-clang-format -- "$staged_files"
+          git add "$staged_files"
+          exit 0
+    else
+          echo "No changes were made to the git config."
+          exit 1
+    fi
+
+fi
+
+
+# Everything checks out
+echo "All staged files have been formatted with git-clang-format."
+exit 0
diff --git a/libcxx/utils/formatting/setup-formatting-config.sh b/libcxx/utils/formatting/setup-formatting-config.sh
new file mode 100755
index 000000000000000..9332ee9e9adebac
--- /dev/null
+++ b/libcxx/utils/formatting/setup-formatting-config.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+
+# Jump up to the root directory of the repository
+
+git_repo_path="$(git rev-parse --show-toplevel)"
+cd "$git_repo_path"
+
+# Set up git-clang-format config so that it formats files without extensions as needed by libc++
+function check_formatting_config() {
+  # Set the desired git config key and value
+  CONFIG_KEY="clangFormat.extensions"
+  CONFIG_VALUE=" c,h,m,mm,cpp,cxx,hpp,,"
+
+  # Get the actual value of the config key
+  ACTUAL_VALUE=$(git config --local --get $CONFIG_KEY)
+
+  # Check if the actual value is the same as the desired value
+  if [[ "$ACTUAL_VALUE" == "$CONFIG_VALUE" ]]; then
+      echo "The git config value for $CONFIG_KEY is correctly set to $CONFIG_VALUE"
+  else
+      echo "Setting up git-clang-format config for libc++..."
+      # Prompt the user to set the git config key to the desired value
+      echo "Git config key $CONFIG_KEY is not set or incorrect."
+      read -p "Would you like to set it to $CONFIG_VALUE [Y/n]? " -n 1 -r
+      echo
+      if [[ $REPLY =~ ^[Yy]$ ]]
+      then
+          git config --local $CONFIG_KEY "$CONFIG_VALUE"
+          echo "Git config key $CONFIG_KEY has been set to $CONFIG_VALUE"
+      else
+          echo "No changes were made to the git config."
+      fi
+  fi
+}
+
+# Check for an installation of git-clang-format
+function check_clang_format() {
+  # Check if git-clang-format is installed
+  GIT_CLANG_FORMAT_COMMAND="git-clang-format"
+  if command -v $GIT_CLANG_FORMAT_COMMAND >/dev/null 2>&1; then
+      echo "git-clang-format is installed in your system."
+  else
+      echo "Warning: git-clang-format is not installed in your system."
+  fi
+}
+# ...
+# Existing script here
+# ...
+
+# Check if libcxx-formatting.sh is installed in pre-commit hook
+function check_pre_commit_hooks() {
+  # Check if libcxx-formatting.sh is present in pre-commit hook
+  PRE_COMMIT_FILE=".git/hooks/pre-commit"
+  EXPECTED_COMMIT_SCRIPT=". ./libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh"
+  if grep -q -F "$EXPECTED_COMMIT_SCRIPT" "$PRE_COMMIT_FILE"; then
+      echo "libcxx-pre-commit-formatting-hook.sh is already installed in pre-commit hook."
+  else
+      # Offer to install it
+      read -p "libcxx-pre-commit-formatting-hook.sh is not installed. Would you like to install it [Y/n]? " -n 1 -r
+      echo
+      if [[ $REPLY =~ ^[Yy]$ ]]
+      then
+          echo "Installing libcxx-pre-commit-formatting-hook.sh..."
+          echo "$EXPECTED_COMMIT_SCRIPT" >> "$PRE_COMMIT_FILE"
+          echo "Installed libcxx-pre-commit-formatting-hook.sh to pre-commit hook."
+      else
+          echo "No changes were made to the pre-commit hook."
+      fi
+  fi
+}
+
+check_formatting_config
+check_clang_format
+check_pre_commit_hooks

>From b50ac103f449eb570460754893122dd0c6296204 Mon Sep 17 00:00:00 2001
From: eric <eric at efcs.ca>
Date: Wed, 29 Nov 2023 10:30:34 -0500
Subject: [PATCH 2/3] Attempt to use the new check on the bots.

---
 .../libcxx-check-generated-files.yml          | 21 +++++++++----
 ...-config.sh => install-formatting-hooks.sh} | 31 +++++++++++++------
 ...-hook.sh => pre-commit-formatting-hook.sh} | 30 +++++++++++++-----
 3 files changed, 59 insertions(+), 23 deletions(-)
 rename libcxx/utils/formatting/{setup-formatting-config.sh => install-formatting-hooks.sh} (68%)
 rename libcxx/utils/formatting/{libcxx-pre-commit-formatting-hook.sh => pre-commit-formatting-hook.sh} (55%)

diff --git a/.github/workflows/libcxx-check-generated-files.yml b/.github/workflows/libcxx-check-generated-files.yml
index 570055624b2a8d4..f6e9b8e04c89c00 100644
--- a/.github/workflows/libcxx-check-generated-files.yml
+++ b/.github/workflows/libcxx-check-generated-files.yml
@@ -9,16 +9,25 @@ permissions:
 
 jobs:
   check_generated_files:
-    runs-on: ubuntu-latest
+    runs-on: [ libcxx-runners-1 ]
     steps:
       - name: Fetch LLVM sources
         uses: actions/checkout at v4
-
-      - name: Install dependencies
-        uses: aminya/setup-cpp at v1
         with:
-          clangformat: 17.0.1
-          ninja: true
+          fetch-depth: 0
+      - name: Install Precommit Hooks
+        run: bash ./libcxx/utils/formatting/install-formatting-hooks.sh --force
+
+      - name: Setup the paths to check for formatting
+        run: git config --local llvmPrecommit.formatPaths "libcxx"
+
+      # Reset the git branch to have all of the modified files staged but not committed.
+      - name: Reset git state
+        run: git reset --soft ${{ github.base_ref }}
+
+      - name: Check generated files
+        run: bash ./libcxx/utils/formatting/pre-commit-formatting-hook.sh
+
 
       - name: Check generated files
         run: libcxx/utils/ci/run-buildbot check-generated-output
diff --git a/libcxx/utils/formatting/setup-formatting-config.sh b/libcxx/utils/formatting/install-formatting-hooks.sh
similarity index 68%
rename from libcxx/utils/formatting/setup-formatting-config.sh
rename to libcxx/utils/formatting/install-formatting-hooks.sh
index 9332ee9e9adebac..5880e7bff8ab537 100755
--- a/libcxx/utils/formatting/setup-formatting-config.sh
+++ b/libcxx/utils/formatting/install-formatting-hooks.sh
@@ -2,6 +2,14 @@
 
 
 # Jump up to the root directory of the repository
+FORCE=${LLVM_FORCE_FORMATTING:-0}
+
+for arg in "$@"
+do
+  if [ "$arg" = "--force" ]; then
+    FORCE=1
+  fi
+done
 
 git_repo_path="$(git rev-parse --show-toplevel)"
 cd "$git_repo_path"
@@ -9,8 +17,9 @@ cd "$git_repo_path"
 # Set up git-clang-format config so that it formats files without extensions as needed by libc++
 function check_formatting_config() {
   # Set the desired git config key and value
-  CONFIG_KEY="clangFormat.extensions"
-  CONFIG_VALUE=" c,h,m,mm,cpp,cxx,hpp,,"
+  CONFIG_KEY=$1
+  CONFIG_VALUE=$2
+  ALLOW_DIFFERENT=$3
 
   # Get the actual value of the config key
   ACTUAL_VALUE=$(git config --local --get $CONFIG_KEY)
@@ -18,11 +27,13 @@ function check_formatting_config() {
   # Check if the actual value is the same as the desired value
   if [[ "$ACTUAL_VALUE" == "$CONFIG_VALUE" ]]; then
       echo "The git config value for $CONFIG_KEY is correctly set to $CONFIG_VALUE"
+  elif [[ "$ACTION_VALUE" != "" ]] && [[ "$ALLOW_DIFFERENT" -eq 1 ]]; then
+    echo "The git config value for $CONFIG_KEY is set to $ACTUAL_VALUE, but $CONFIG_VALUE is allowed."
   else
       echo "Setting up git-clang-format config for libc++..."
       # Prompt the user to set the git config key to the desired value
       echo "Git config key $CONFIG_KEY is not set or incorrect."
-      read -p "Would you like to set it to $CONFIG_VALUE [Y/n]? " -n 1 -r
+      read -p "Would you like to set it to $CONFIG_VALUE [Y/n]? " -n $FORCE -r
       echo
       if [[ $REPLY =~ ^[Yy]$ ]]
       then
@@ -52,24 +63,26 @@ function check_clang_format() {
 function check_pre_commit_hooks() {
   # Check if libcxx-formatting.sh is present in pre-commit hook
   PRE_COMMIT_FILE=".git/hooks/pre-commit"
-  EXPECTED_COMMIT_SCRIPT=". ./libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh"
+  EXPECTED_COMMIT_SCRIPT=". ./libcxx/utils/formatting/pre-commit-formatting-hook.sh"
   if grep -q -F "$EXPECTED_COMMIT_SCRIPT" "$PRE_COMMIT_FILE"; then
-      echo "libcxx-pre-commit-formatting-hook.sh is already installed in pre-commit hook."
+      echo "pre-commit-formatting-hook.sh is already installed in pre-commit hook."
   else
       # Offer to install it
-      read -p "libcxx-pre-commit-formatting-hook.sh is not installed. Would you like to install it [Y/n]? " -n 1 -r
+      read -p "pre-commit-formatting-hook.sh is not installed. Would you like to install it [Y/n]? " -n $FORCE -r
       echo
       if [[ $REPLY =~ ^[Yy]$ ]]
       then
-          echo "Installing libcxx-pre-commit-formatting-hook.sh..."
+          echo "Installing pre-commit-formatting-hook.sh..."
           echo "$EXPECTED_COMMIT_SCRIPT" >> "$PRE_COMMIT_FILE"
-          echo "Installed libcxx-pre-commit-formatting-hook.sh to pre-commit hook."
+          chmod +x "$PRE_COMMIT_FILE"
+          echo "Installed pre-commit-formatting-hook.sh to pre-commit hook."
       else
           echo "No changes were made to the pre-commit hook."
       fi
   fi
 }
 
-check_formatting_config
+check_formatting_config "clangFormat.extensions" "c,h,m,mm,cpp,cxx,hpp,," 0
+check_formatting_config "llvmPrecommit.formatPaths" "libcxx libcxxabi libunwind" 1
 check_clang_format
 check_pre_commit_hooks
diff --git a/libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh b/libcxx/utils/formatting/pre-commit-formatting-hook.sh
similarity index 55%
rename from libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh
rename to libcxx/utils/formatting/pre-commit-formatting-hook.sh
index 741b686e5e5a402..fb04a7ec318c73e 100755
--- a/libcxx/utils/formatting/libcxx-pre-commit-formatting-hook.sh
+++ b/libcxx/utils/formatting/pre-commit-formatting-hook.sh
@@ -1,28 +1,42 @@
 #!/bin/bash
+set -x
+set -e
+FORCE=${LLVM_FORCE_FORMATTING:-0}
+VERBOSE=${VERBOSE:-0}
+
+for arg in "$@"
+do
+  if [ "$arg" = "--force" ]; then
+    FORCE=1
+  fi
+done
+
+FORMAT_PATHS=$(git config --get llvmPrecommit.formatPaths || echo ".")
+
+echo "FORMAT_PATHS is set to: $FORMAT_PATHS"
 
 
 # Define the staged files
-staged_files=$(git diff --cached --name-only --diff-filter=d -- libcxx/ libcxxabi/ libunwind/)
+staged_files=$(git diff --cached --name-only --diff-filter=d -- $FORMAT_PATHS)
 
 # Check if any of the staged files have not been properly formatted with git-clang-format
 
 echo "Checking $file..."
-formatting_diff=$(git-clang-format --diff -- "$staged_files") # quotes are used here
+formatting_diff=$(git-clang-format --diff -- $staged_files) # quotes are used here
 if [[ "$formatting_diff" != "no modified files to format" && "$formatting_diff" != "clang-format did not modify any files" ]]; then
     echo "$file has not been formatted with git-clang-format."
-    git-clang-format --diff -- "$staged_files"
-    read -p "Format the files [Y/n]? " -n 1 -r
+    git-clang-format --diff -- $staged_files
+    read -p "Format the files [Y/n]? " -n $FORCE -r
       echo
     if [[ $REPLY =~ ^[Yy]$ ]]
-      then
-          git-clang-format -- "$staged_files"
-          git add "$staged_files"
+    then
+          git-clang-format -- $staged_files
+          git add $staged_files
           exit 0
     else
           echo "No changes were made to the git config."
           exit 1
     fi
-
 fi
 
 

>From 8d0330002c17718933f70551df921682046f33ba Mon Sep 17 00:00:00 2001
From: eric <eric at efcs.ca>
Date: Wed, 29 Nov 2023 10:59:49 -0500
Subject: [PATCH 3/3] fix group name

---
 .github/workflows/libcxx-check-generated-files.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/libcxx-check-generated-files.yml b/.github/workflows/libcxx-check-generated-files.yml
index f6e9b8e04c89c00..96da89855fc4f5e 100644
--- a/.github/workflows/libcxx-check-generated-files.yml
+++ b/.github/workflows/libcxx-check-generated-files.yml
@@ -9,7 +9,8 @@ permissions:
 
 jobs:
   check_generated_files:
-    runs-on: [ libcxx-runners-1 ]
+    runs-on:
+      group: libcxx-runners-1
     steps:
       - name: Fetch LLVM sources
         uses: actions/checkout at v4



More information about the llvm-commits mailing list