From 5f497fe9e20cc414113f46b5b97a88e4cb77aef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Fri, 30 Oct 2026 20:05:36 +0100 Subject: Last tag selection based on creation time --- minici.cabal | 1 + src/Expression.hs | 9 +++++ src/Repo.hs | 9 +++++ test/script/expression.et | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) diff --git a/minici.cabal b/minici.cabal index 0bb59a2..217d5ba 100644 --- a/minici.cabal +++ b/minici.cabal @@ -106,6 +106,7 @@ executable minici temporary ^>= { 1.3 }, text ^>= { 1.2, 2.0, 2.1 }, th-compat ^>= { 0.1 }, + time ^>= { 1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16 }, unix ^>= { 2.7.2, 2.8.4 }, hs-source-dirs: src diff --git a/src/Expression.hs b/src/Expression.hs index 994912e..bf35f2a 100644 --- a/src/Expression.hs +++ b/src/Expression.hs @@ -31,6 +31,7 @@ import Data.Maybe import Data.Proxy import Data.Text (Text) import Data.Text qualified as T +import Data.Time.LocalTime import Data.Void import Text.Megaparsec @@ -277,6 +278,9 @@ parseRangeExpression = bimap errorBundlePretty id . runParser parser "" "highesttag" -> do pat <- parseTagPattern return $ SingleRevisionExpression $ StaticRef $ TagRef pat higherTag + "lasttag" -> do + pat <- parseTagPattern + return $ SingleRevisionExpression $ StaticRef $ TagRef pat laterTag _ -> unexpected $ Tokens $ NE.fromList $ chunkToTokens @Text Proxy tok , do @@ -306,3 +310,8 @@ higherTag t t' = Left $ read @Integer $ T.unpack s | otherwise = Right s + +laterTag :: Tag a -> Tag a -> Tag a +laterTag t t' + | zonedTimeToUTC (tagTime t) < zonedTimeToUTC (tagTime t') = t' + | otherwise = t diff --git a/src/Repo.hs b/src/Repo.hs index b6ad8d4..7fe699c 100644 --- a/src/Repo.hs +++ b/src/Repo.hs @@ -52,6 +52,8 @@ import Data.Maybe import Data.Text (Text) import Data.Text qualified as T import Data.Text.Encoding +import Data.Time.Format +import Data.Time.LocalTime import System.Environment import System.Exit @@ -118,6 +120,8 @@ data Tag a = Tag { tagTag :: Text , tagId :: TagId , tagObject :: a + , tagTagger :: Text + , tagTime :: ZonedTime , tagMessage :: Text } @@ -263,6 +267,11 @@ tryReadTag repo tag = do guard (otype == "commit") tagTag <- T.pack <$> lookup "tag" info cid <- CommitId . BC.pack <$> lookup "object" info + + tagger <- T.pack <$> lookup "tagger" info + let tagTagger = T.dropEnd 1 $ T.dropWhileEnd (/= ' ') $ T.dropEnd 1 $ T.dropWhileEnd (/= ' ') tagger + tagTime <- parseTimeM False defaultTimeLocale "%s %z" $ T.unpack $ T.drop (T.length tagTagger + 1) tagger + let tagMessage = T.pack $ unlines $ dropWhile null message Just $ do tagObject <- liftIO $ mkCommit repo cid diff --git a/test/script/expression.et b/test/script/expression.et index bbb312a..ce48c93 100644 --- a/test/script/expression.et +++ b/test/script/expression.et @@ -360,3 +360,103 @@ test WatchHighestTag: expect from p: /job-start $td:single/ /job-finish $td:single done/ + + +test WatchLastTag: + node n + shell on n as git_init: + git -c init.defaultBranch=master init -q + git -c user.name=test -c user.email=test commit -q --allow-empty -m 'initial commit' + cp "${scripts.path}/single.yaml" minici.yaml + git add minici.yaml + git -c user.name=test -c user.email=test commit -q -m 'minici.yaml' + git rev-parse HEAD + + touch a + git add a + git -c user.name=test -c user.email=test commit -q -m a + git rev-parse HEAD + git rev-parse HEAD^{tree} + + touch b + git add b + git -c user.name=test -c user.email=test commit -q -m b + git rev-parse HEAD + git rev-parse HEAD^{tree} + + touch c + git add c + git -c user.name=test -c user.email=test commit -q -m c + git rev-parse HEAD + git rev-parse HEAD^{tree} + + touch d + git add d + git -c user.name=test -c user.email=test commit -q -m d + git rev-parse HEAD + git rev-parse HEAD^{tree} + + touch e + git add e + git -c user.name=test -c user.email=test commit -q -m e + git rev-parse HEAD + git rev-parse HEAD^{tree} + + git reset --hard HEAD~5 + git rev-parse HEAD + + expect /([0-9a-f]+)/ from git_init capture c_init + expect /([0-9a-f]+)/ from git_init capture ca + expect /([0-9a-f]+)/ from git_init capture ta + expect /([0-9a-f]+)/ from git_init capture cb + expect /([0-9a-f]+)/ from git_init capture tb + expect /([0-9a-f]+)/ from git_init capture cc + expect /([0-9a-f]+)/ from git_init capture tc + expect /([0-9a-f]+)/ from git_init capture cd + expect /([0-9a-f]+)/ from git_init capture td + expect /([0-9a-f]+)/ from git_init capture ce + expect /([0-9a-f]+)/ from git_init capture te + expect /([0-9a-f]+)/ from git_init capture c_end + + guard (c_init == c_end) + + shell on n: + env GIT_COMMITTER_DATE='2020-01-01 02:00' git -c user.name=test -c user.email=test tag -a -m . v1 $cb + env GIT_COMMITTER_DATE='2020-01-01 00:00' git -c user.name=test -c user.email=test tag -a -m . v2 $cc + + local: + spawn on n as p args [ "run", "--rerun-all", "lasttag(v*)" ] + expect from p: + /job-enqueue $tb:single/ + /job-start $tb:single/ + /job-finish $tb:single done/ + expect /(.*)/ from p capture finish + guard (finish == "run-finish") + + local: + spawn on n as p args [ "run", "--rerun-all", "watch(lasttag(v*))" ] killwith SIGINT + expect from p: + /job-enqueue $tb:single/ + /job-start $tb:single/ + /job-finish $tb:single done/ + + shell on n: + env GIT_COMMITTER_DATE='2020-01-01 02:00' git -c user.name=test -c user.email=test tag -a -m . v3 $ca + + expect from p: + /job-enqueue $ta:single/ + /job-start $ta:single/ + /job-finish $ta:single done/ + + shell on n: + env GIT_COMMITTER_DATE='2020-01-01 01:00' git -c user.name=test -c user.email=test tag -a -m . v4 $ce + + shell on n: + env GIT_COMMITTER_DATE='2020-01-01 02:00' git -c user.name=test -c user.email=test tag -a -m . v5 $cd + + local: + expect from p /job-enqueue ([0-9a-f]+):single/ capture tid + guard (tid == td) + expect from p: + /job-start $td:single/ + /job-finish $td:single done/ -- cgit v1.2.3