Stream: nix

Topic: Check whether generated code is in sync


view this post on Zulip Vijay Gupta (Dec 12 2023 at 12:44):

I have a Haskell project that uses nix.

We have a local cabal package take takes bunch of yaml files and generates Haskell code. Both the yaml file and generated code are checked into git. Anytime somebody changes the yaml files they must remember to regenerate the code. If they forgot to regenerate the code and thereby the yaml and Haskell code is out of sync then CI should fail accordingly.

The CI runs nix. How do we have this check in nix. We currently have a bash script that regenerates the code and looks for the diff.

view this post on Zulip Vijay Gupta (Dec 12 2023 at 12:44):

https://github.com/nammayatri/nammayatri

view this post on Zulip Vijay Gupta (Dec 12 2023 at 12:46):

This is my shell script

#!/bin/bash


cabal run alchemist-generator-exe
treefmt
# This script checks if there are any changes in the src-read-only folder
CHANGES_FOUND=false

git diff --unified=0 -- | grep -E "^\\+\\+\\+|^@@" | while read -r line; do
    file_path=$(grep -oP "^\\+\\+\\+ b/\K(.+)" <<< "$line")
    if [[ $file_path == *"/src-read-only/"* ]]; then
        git diff --unified=0 --relative="$file_path" | grep -E "^@@" | while read -r diff_line; do
            line_number=$(grep -oP "@@\\s-\\d+(,\d+)?\\s+\\+\\K\d+" <<< "$diff_line")
            echo $file_path:$line_number:"Changes found in src-read-only folder with diff line: $diff_line"
            CHANGES_FOUND=true
        done
    fi
done

# git checkout -- .

if [ "$CHANGES_FOUND" = true ]; then
    exit 1
else
    exit 0

fi

view this post on Zulip Srid (Dec 12 2023 at 12:50):

You can use pre-commit to do this check. Flakes also has support for it.

In fact, the nammayatri repo already uses it for checking a similar thing (overlapping migrations), so you can use the same approach.

view this post on Zulip Srid (Dec 12 2023 at 12:50):

Instead of using cabal run, however, you'd have to use the Nix package itself (lib.getExe self.packages.${pkgs.system}.alchemist-whatever).

view this post on Zulip Srid (Dec 12 2023 at 13:03):

There's one limitation to be aware of with pre-commit-hooks.nix. There's no user-defined ordering yet; https://github.com/cachix/pre-commit-hooks.nix/issues/250

view this post on Zulip Vijay Gupta (Dec 13 2023 at 09:44):

I am currently working on a pre-commit hook for this project to check diff, aiming to run both a package and a formatter in the same hook. However, I am encountering an issue where the formatter fails to run after the package execution.

Here's a snippet of the relevant configuration:

check-src-read-only-diff-check = {
  enable = true;
  name = "check-src-read-only-diff-check";
  description = "Check that src-read-only folder is read-only";
  types = [ "file" ];
  pass_filenames = true;
  files = ".*\\/((rider-platform\\/rider-app)|(provider-platform\\/dynamic-offer-driver-app))\\/Main\\/src-read-only\\/.*\\.hs$";
  entry = "bash -c '${lib.getExe self'.packages.alchemist}' ; bash -c '${lib.getExe config.treefmt.programs.ormolu.package}'";
};

The issue arises after the package execution, preventing the formatter from running successfully. Am i doing something wrong here ?

Any help or suggestions regarding the correct configuration or execution order would be greatly appreciated.

view this post on Zulip Shivaraj B H (Dec 13 2023 at 09:51):

How did you confirm that the package is running? If it is running and the formatter is not, one possible explanation could be that your package might be a service that doesn't complete, is it?

view this post on Zulip Vijay Gupta (Dec 13 2023 at 09:56):

Well package is supposed to generate the new unformatted files, which it is generating . Now the next thing i wanted was the formatter should format the files and after formatting if there are still new files in staged area i want the commit to be failed

view this post on Zulip Shivaraj B H (Dec 13 2023 at 10:08):

let me put forward a scenario, let's assume you make changes to your yaml files, the .hs files for these changes are not generated yet.
Now you proceed to commit these yaml files and when you do alchemist package and sequentially ormolu runs and generates formatted .hs files, these files will not match the already existing .hs files and the commit will fail.

The above mentioned is the ideal scenario and you are saying that alchemist is running, failing the commit, but the formatter is not running after alchemist? is my understanding here correct?

view this post on Zulip Vijay Gupta (Dec 13 2023 at 10:29):

So what we do is, we first put some change in yaml file. After that we run the alchemist-generator which is nix command which generates and formats the code. We stage those changes i.e. yaml and newly generated file.
Now, When I'm trying to commit i want the pre-commit to work in a such a way that It will first run the alchemist-generator which will generate the same code but it will be unformatted code.Hence, it will have diff between staged and newly code generated . Now my goal is to format those newly generated code by ormulo and after that as we haven't made any change
all those files will be same as staged one and hence no file will be there in Unstaged area.
I want my pre-commit to fail only if the staged code is different from the unstaged code generated during pre-commit.
But with my pre-commit it's failing everytime as code is generated during pre-commit run but fails to format it.

view this post on Zulip Vijay Gupta (Dec 13 2023 at 10:50):

to check if the formatter is working, I removed bash -c '${lib.getExe self'.packages.alchemist}' from the code and tried to format unformatted file using this hook. It didn't format those files.

view this post on Zulip Shivaraj B H (Dec 13 2023 at 11:11):

If your formatter is not working, most probable culprit could be the regex you have to detect the files, assuming rest of the configuration is correct.


Last updated: Nov 15 2024 at 12:33 UTC