Skip to content

Commit da18ff5

Browse files
fix: open files read-only during format --check
format --check only reads files to compare content but opened them with r+, which requires write permission and fails on read-only filesystems in certain CI setups. Use r for check mode and keep r+ for normal format runs that write back to disk. Signed-off-by: Amir Vakili <AVakili@Voleon.com>
1 parent 7bd09ef commit da18ff5

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

sqlmesh/core/context.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1270,7 +1270,8 @@ def format(
12701270
): # introduced to satisfy type checker as still want to pull filter out as many targets as possible before loop
12711271
continue
12721272

1273-
with open(target._path, "r+", encoding="utf-8") as file:
1273+
mode = "r" if check else "r+"
1274+
with open(target._path, mode, encoding="utf-8") as file:
12741275
before = file.read()
12751276

12761277
after = self._format(

tests/core/test_format.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import os
12
import pathlib
3+
import stat
24

35
from pytest_mock.plugin import MockerFixture
46
from sqlmesh.core.config import Config
@@ -146,6 +148,25 @@ def test_ignore_formating_files(tmp_path: pathlib.Path):
146148
)
147149

148150

151+
def test_format_check_read_only_files(tmp_path: pathlib.Path, mocker: MockerFixture):
152+
models_dir = pathlib.Path("models")
153+
154+
model_text = "MODEL(name this.model, dialect 'duckdb'); SELECT 1 AS col"
155+
model = create_temp_file(
156+
tmp_path,
157+
pathlib.Path(models_dir, "model.sql"),
158+
model_text,
159+
)
160+
os.chmod(model, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
161+
162+
context = Context(paths=tmp_path, config=Config())
163+
context.console = mocker.Mock()
164+
context.load()
165+
166+
assert not context.format(check=True)
167+
assert model.read_text(encoding="utf-8") == model_text
168+
169+
149170
def test_format_without_state_load(tmp_path: pathlib.Path, mocker: MockerFixture):
150171
mock = mocker.patch(
151172
"sqlmesh.core.state_sync.db.facade.EngineAdapterStateSync.get_versions",

0 commit comments

Comments
 (0)