summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2026-10-30 20:05:36 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2026-10-30 20:22:23 +0100
commit5f497fe9e20cc414113f46b5b97a88e4cb77aef9 (patch)
treeb083fe04ecd0a73107e186e7098fdbc610e4c23a
parent09df29c85950e4908dbabeceb503ce3764f32561 (diff)
Last tag selection based on creation time
-rw-r--r--minici.cabal1
-rw-r--r--src/Expression.hs9
-rw-r--r--src/Repo.hs9
-rw-r--r--test/script/expression.et100
4 files changed, 119 insertions, 0 deletions
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/