From 8d52febbc5c5d0a2e868a5f41b379914f41a858d Mon Sep 17 00:00:00 2001
From: Boming Zhang <bomingzh@sjtu.edu.cn>
Date: Fri, 20 Jun 2025 17:06:57 -0400
Subject: [PATCH] feat: new immutable dir (#25)

---
 joj3_config_generator/models/repo.py                |  4 ++++
 joj3_config_generator/transformers/repo.py          | 13 +++++++++++++
 .../{immutable_files => immutable}/.gitattributes   |  0
 .../.gitea/workflows}/push.yaml                     |  0
 .../.gitea/workflows}/release.yaml                  |  0
 .../basic/{immutable_files => immutable}/.gitignore |  0
 tests/convert/basic/repo.toml                       |  2 ++
 tests/convert/basic/task.json                       |  4 ++--
 8 files changed, 21 insertions(+), 2 deletions(-)
 rename tests/convert/basic/{immutable_files => immutable}/.gitattributes (100%)
 rename tests/convert/basic/{immutable_files => immutable/.gitea/workflows}/push.yaml (100%)
 rename tests/convert/basic/{immutable_files => immutable/.gitea/workflows}/release.yaml (100%)
 rename tests/convert/basic/{immutable_files => immutable}/.gitignore (100%)

diff --git a/joj3_config_generator/models/repo.py b/joj3_config_generator/models/repo.py
index ea2dc84..f200cde 100644
--- a/joj3_config_generator/models/repo.py
+++ b/joj3_config_generator/models/repo.py
@@ -70,6 +70,10 @@ class Config(BaseModel):
         0, validation_alias=AliasChoices("health-check-score", "health_check_score")
     )
     issue: Issue = Issue()
+    immutable_path: Path = Field(
+        Path("immutable_files"),
+        validation_alias=AliasChoices("immutable-path", "immutable_path"),
+    )
 
     @model_validator(mode="after")
     def set_grading_repo_name_from_cwd(self) -> "Config":
diff --git a/joj3_config_generator/transformers/repo.py b/joj3_config_generator/transformers/repo.py
index 1dd1cbf..a2b0924 100644
--- a/joj3_config_generator/transformers/repo.py
+++ b/joj3_config_generator/transformers/repo.py
@@ -99,6 +99,19 @@ def get_check_lists(repo_conf: repo.Config) -> Tuple[List[str], List[str]]:
         immutable_files.append(file_path)
         file_sums.append(calc_sha256sum(file_path))
         file_names.append(file)
+    immutable_dir = (repo_conf.root / repo_conf.path).parent / repo_conf.immutable_path
+    if not immutable_dir.exists():
+        return file_sums, file_names
+    file_sums = []
+    file_names = []
+    for file_path in immutable_dir.glob("**/*"):
+        if file_path.is_dir():
+            continue
+        if not file_path.exists():
+            logger.warning(f"Immutable file not found: {file_path}")
+            continue
+        file_sums.append(calc_sha256sum(file_path))
+        file_names.append(file_path.relative_to(immutable_dir).as_posix())
     return file_sums, file_names
 
 
diff --git a/tests/convert/basic/immutable_files/.gitattributes b/tests/convert/basic/immutable/.gitattributes
similarity index 100%
rename from tests/convert/basic/immutable_files/.gitattributes
rename to tests/convert/basic/immutable/.gitattributes
diff --git a/tests/convert/basic/immutable_files/push.yaml b/tests/convert/basic/immutable/.gitea/workflows/push.yaml
similarity index 100%
rename from tests/convert/basic/immutable_files/push.yaml
rename to tests/convert/basic/immutable/.gitea/workflows/push.yaml
diff --git a/tests/convert/basic/immutable_files/release.yaml b/tests/convert/basic/immutable/.gitea/workflows/release.yaml
similarity index 100%
rename from tests/convert/basic/immutable_files/release.yaml
rename to tests/convert/basic/immutable/.gitea/workflows/release.yaml
diff --git a/tests/convert/basic/immutable_files/.gitignore b/tests/convert/basic/immutable/.gitignore
similarity index 100%
rename from tests/convert/basic/immutable_files/.gitignore
rename to tests/convert/basic/immutable/.gitignore
diff --git a/tests/convert/basic/repo.toml b/tests/convert/basic/repo.toml
index a6e7035..cf8d457 100644
--- a/tests/convert/basic/repo.toml
+++ b/tests/convert/basic/repo.toml
@@ -5,6 +5,8 @@ sandbox-token = "test"
 max-total-score = 1000
 max-size = 50.5
 
+immutable_path = "immutable"
+
 # for tests
 [groups]
 name = ["joj", "run"]
diff --git a/tests/convert/basic/task.json b/tests/convert/basic/task.json
index 7db50dc..05a963b 100644
--- a/tests/convert/basic/task.json
+++ b/tests/convert/basic/task.json
@@ -64,8 +64,8 @@
                                     "-repoSize=50.5",
                                     "-meta=README.md",
                                     "-meta=Changelog.md",
-                                    "-checkFileSumList=a5b63323a692d3d8b952442969649b4f823d58dae26429494f613df160710dfc,b1bbad25b830db0a77b15a033f9ca1b7ab44c1d2d05056412bd3e4421645f0bf,2ba059f3977e2e3dee6cacbfbf0ba2578baa1b8e04b4977aec400868b6e49856,3db23f7fb2ca9814617e767ddc41b77073180b3b0b73e87b5f2a6d3129f88f3a",
-                                    "-checkFileNameList=.gitignore,.gitattributes,.gitea/workflows/push.yaml,.gitea/workflows/release.yaml"
+                                    "-checkFileSumList=b1bbad25b830db0a77b15a033f9ca1b7ab44c1d2d05056412bd3e4421645f0bf,a5b63323a692d3d8b952442969649b4f823d58dae26429494f613df160710dfc,2ba059f3977e2e3dee6cacbfbf0ba2578baa1b8e04b4977aec400868b6e49856,3db23f7fb2ca9814617e767ddc41b77073180b3b0b73e87b5f2a6d3129f88f3a",
+                                    "-checkFileNameList=.gitattributes,.gitignore,.gitea/workflows/push.yaml,.gitea/workflows/release.yaml"
                                 ]
                             },
                             {