From 9551c2222ff6ed2d650f888ecdcfb3e774f9bab7 Mon Sep 17 00:00:00 2001 From: Jonatan Borkowski Date: Fri, 4 Jul 2025 07:38:17 +0000 Subject: [PATCH 1/3] Skip restoring cache if working tree is not clean --- src/App.hs | 6 ++++-- src/Utils.hs | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/App.hs b/src/App.hs index 825e48d..64b4474 100644 --- a/src/App.hs +++ b/src/App.hs @@ -425,6 +425,8 @@ snapshot appState args = do mainBranchCommit <- liftIO $ getMainBranchCommit appState let force = appState.settings.force + isWorkingTreeClean <- map not $ liftIO $ hasLocalChanges appState + let hashInfo = HashInfo { hash = currentHash , hashInput = currentHashInput @@ -447,7 +449,7 @@ snapshot appState args = do earlyReturn (False, Nothing) - when (hasRemoteCache args && not force) do + when (hasRemoteCache args && not force && isWorkingTreeClean) do s <- RemoteCache.getRemoteCacheSettingsFromEnv success <- liftIO $ RemoteCache.restoreCache appState s (fromMaybe appState.settings.rootDirectory args.cacheRoot) (archiveName appState args currentHash) RemoteCache.Log when success do @@ -456,7 +458,7 @@ snapshot appState args = do logInfo appState "Inputs changed, running task" - when (not force && hasRemoteCache args && args.fuzzyCache && mainBranchCommitChanged savedHashInfo hashInfo) do + when (not force && hasRemoteCache args && args.fuzzyCache && mainBranchCommitChanged savedHashInfo hashInfo && isWorkingTreeClean) do success <- tryRestoreFuzzyCache appState args when success do -- Save change in mainBranchCommit, even if the task didn't succeed yet. diff --git a/src/Utils.hs b/src/Utils.hs index 7a3b6df..a862765 100644 --- a/src/Utils.hs +++ b/src/Utils.hs @@ -80,6 +80,17 @@ bytesfmt formatter bs = printf (formatter <> " %s") bytesSuffixes = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"] bytesSuffix = bytesSuffixes !! i +hasLocalChanges :: AppState -> IO Bool +hasLocalChanges appState = + bracket (hDuplicate appState.subprocessStderr) hClose \stderr_ -> do + output <- + readCreateProcess + (proc "git" ["status", "--porcelain", "--untracked-files=no"]) + { std_err = UseHandle stderr_ + } + "" + pure $ not (null output) + getCurrentBranch :: AppState -> IO Text getCurrentBranch appState = bracket (hDuplicate appState.subprocessStderr) hClose \stderr_ -> From aca5c5ddb71a9576a7273e4f4a146dc2c2e2bffd Mon Sep 17 00:00:00 2001 From: Jonatan Borkowski Date: Fri, 4 Jul 2025 08:07:15 +0000 Subject: [PATCH 2/3] Rename and focus on inputFiles --- src/App.hs | 7 +++---- src/Utils.hs | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/App.hs b/src/App.hs index 64b4474..c4bf92c 100644 --- a/src/App.hs +++ b/src/App.hs @@ -425,7 +425,7 @@ snapshot appState args = do mainBranchCommit <- liftIO $ getMainBranchCommit appState let force = appState.settings.force - isWorkingTreeClean <- map not $ liftIO $ hasLocalChanges appState + inputsAreClean <- liftIO $ not <$> isDirtyAtPaths appState args.fileInputs let hashInfo = HashInfo { hash = currentHash @@ -448,8 +448,7 @@ snapshot appState args = do logDebug appState "Prime cache mode, assuming task is done and skippping!" earlyReturn (False, Nothing) - - when (hasRemoteCache args && not force && isWorkingTreeClean) do + when (hasRemoteCache args && not force && inputsAreClean) do s <- RemoteCache.getRemoteCacheSettingsFromEnv success <- liftIO $ RemoteCache.restoreCache appState s (fromMaybe appState.settings.rootDirectory args.cacheRoot) (archiveName appState args currentHash) RemoteCache.Log when success do @@ -458,7 +457,7 @@ snapshot appState args = do logInfo appState "Inputs changed, running task" - when (not force && hasRemoteCache args && args.fuzzyCache && mainBranchCommitChanged savedHashInfo hashInfo && isWorkingTreeClean) do + when (not force && hasRemoteCache args && args.fuzzyCache && mainBranchCommitChanged savedHashInfo hashInfo && inputsAreClean) do success <- tryRestoreFuzzyCache appState args when success do -- Save change in mainBranchCommit, even if the task didn't succeed yet. diff --git a/src/Utils.hs b/src/Utils.hs index a862765..1ab72d6 100644 --- a/src/Utils.hs +++ b/src/Utils.hs @@ -80,12 +80,12 @@ bytesfmt formatter bs = printf (formatter <> " %s") bytesSuffixes = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"] bytesSuffix = bytesSuffixes !! i -hasLocalChanges :: AppState -> IO Bool -hasLocalChanges appState = +isDirtyAtPaths :: AppState -> [FilePath] -> IO Bool +isDirtyAtPaths appState paths = bracket (hDuplicate appState.subprocessStderr) hClose \stderr_ -> do output <- readCreateProcess - (proc "git" ["status", "--porcelain", "--untracked-files=no"]) + (proc "git" (["status", "--porcelain", "--untracked-files=no", "--"] ++ paths)) { std_err = UseHandle stderr_ } "" From f4e7dfe68358366861ad0ad31be4f05b575eb1d2 Mon Sep 17 00:00:00 2001 From: Jonatan Borkowski Date: Fri, 4 Jul 2025 09:25:26 +0000 Subject: [PATCH 3/3] fix snapshots to handle new assumption (files should be committed) --- README.md | 14 +++++++++++++- src/App.hs | 2 +- src/Utils.hs | 1 + test/t/cache-success-unchanged.txt | 1 + test/t/prime-cache-mode.txt | 1 + test/t/remote-cache-changed.txt | 1 + test/t/remote-cache-post-unpack.txt | 1 + test/t/remote-cache-unchanged-force.txt | 1 + test/t/remote-cache-unchanged-nested-dir.txt | 1 + test/t/remote-cache-unchanged-out-of-repo.txt | 1 + test/t/remote-cache-unchanged.txt | 1 + 11 files changed, 23 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e8bb62..fbec0cf 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ To use it, first build using another system, and the run `taskrunner` with `TASK - Previous impl no-op tests/scripts/UPDATE: ~1.6s - Current impl no-op tests/scripts/UPDATE: ~2.3s -## Snapshot Command Flags +## Snapshot Command Flags The `snapshot` command supports the following flags: @@ -142,3 +142,15 @@ The `snapshot` command supports the following flags: - `--cache-version`: Specifies a version string for the cache. `--fuzzy-cache` will not download cache from another version, allowing clean breaks when making big changes, e.g. upgrading a compiler. - `--commit-status`: Enables reporting of the task's status to a commit status system, such as GitHub checks. - `--long-running`: Indicates that the task is expected to run for a long time (e.g. a server). Currently doens't have any effect though, TODO: can we remove it? + + +## Tests: Update Golden Files + +This project uses [tasty-golden](https://github.com/UnkindPartition/tasty-golden) for snapshot-based testing. + +To update the golden files, run the test suite with the `--accept` flag passed to the test executable. +If you're using stack, the full command is: + +```sh +stack test --test-arguments --accept +``` diff --git a/src/App.hs b/src/App.hs index c4bf92c..c8d840b 100644 --- a/src/App.hs +++ b/src/App.hs @@ -457,7 +457,7 @@ snapshot appState args = do logInfo appState "Inputs changed, running task" - when (not force && hasRemoteCache args && args.fuzzyCache && mainBranchCommitChanged savedHashInfo hashInfo && inputsAreClean) do + when (not force && hasRemoteCache args && args.fuzzyCache && mainBranchCommitChanged savedHashInfo hashInfo) do success <- tryRestoreFuzzyCache appState args when success do -- Save change in mainBranchCommit, even if the task didn't succeed yet. diff --git a/src/Utils.hs b/src/Utils.hs index 1ab72d6..508644d 100644 --- a/src/Utils.hs +++ b/src/Utils.hs @@ -81,6 +81,7 @@ bytesfmt formatter bs = printf (formatter <> " %s") bytesSuffix = bytesSuffixes !! i isDirtyAtPaths :: AppState -> [FilePath] -> IO Bool +isDirtyAtPaths _ [] = pure False isDirtyAtPaths appState paths = bracket (hDuplicate appState.subprocessStderr) hClose \stderr_ -> do output <- diff --git a/test/t/cache-success-unchanged.txt b/test/t/cache-success-unchanged.txt index 2785686..40d6537 100644 --- a/test/t/cache-success-unchanged.txt +++ b/test/t/cache-success-unchanged.txt @@ -10,6 +10,7 @@ mkdir a echo foo > input.txt git init -q git add input.txt + git commit -qm "Add input.txt" ) cp -r a b diff --git a/test/t/prime-cache-mode.txt b/test/t/prime-cache-mode.txt index c877a05..888b284 100644 --- a/test/t/prime-cache-mode.txt +++ b/test/t/prime-cache-mode.txt @@ -10,6 +10,7 @@ mkdir a echo foo > input.txt git init -q git add input.txt + git commit -qm "Add input.txt" ) cp -r a b diff --git a/test/t/remote-cache-changed.txt b/test/t/remote-cache-changed.txt index 0e08469..55a6435 100644 --- a/test/t/remote-cache-changed.txt +++ b/test/t/remote-cache-changed.txt @@ -10,6 +10,7 @@ mkdir a echo foo > input.txt git init -q git add input.txt + git commit -qm "Add input.txt" ) cp -r a b diff --git a/test/t/remote-cache-post-unpack.txt b/test/t/remote-cache-post-unpack.txt index 61a0d0a..c764ecc 100644 --- a/test/t/remote-cache-post-unpack.txt +++ b/test/t/remote-cache-post-unpack.txt @@ -10,6 +10,7 @@ mkdir a echo foo > input.txt git init -q git add input.txt + git commit -qm "Add input.txt" ) cp -r a b diff --git a/test/t/remote-cache-unchanged-force.txt b/test/t/remote-cache-unchanged-force.txt index 53988e4..20a9095 100644 --- a/test/t/remote-cache-unchanged-force.txt +++ b/test/t/remote-cache-unchanged-force.txt @@ -10,6 +10,7 @@ mkdir a echo foo > input.txt git init -q git add input.txt + git commit -qm "Add input.txt" ) cp -r a b diff --git a/test/t/remote-cache-unchanged-nested-dir.txt b/test/t/remote-cache-unchanged-nested-dir.txt index e3ddd3e..4b9c10c 100644 --- a/test/t/remote-cache-unchanged-nested-dir.txt +++ b/test/t/remote-cache-unchanged-nested-dir.txt @@ -15,6 +15,7 @@ mkdir -p a cd nested echo foo > input.txt git add input.txt + git commit -qm "Add input.txt" ) cp -r a b diff --git a/test/t/remote-cache-unchanged-out-of-repo.txt b/test/t/remote-cache-unchanged-out-of-repo.txt index 31f7dd7..0723ad0 100644 --- a/test/t/remote-cache-unchanged-out-of-repo.txt +++ b/test/t/remote-cache-unchanged-out-of-repo.txt @@ -10,6 +10,7 @@ mkdir a echo foo > input.txt git init -q git add input.txt + git commit -qm "Add input.txt" ) cp -r a b diff --git a/test/t/remote-cache-unchanged.txt b/test/t/remote-cache-unchanged.txt index 7a9a5a9..143483c 100644 --- a/test/t/remote-cache-unchanged.txt +++ b/test/t/remote-cache-unchanged.txt @@ -10,6 +10,7 @@ mkdir a echo foo > input.txt git init -q git add input.txt + git commit -qm "Add input.txt" ) cp -r a b